ruby mysql timestamp difference - mysql

I am trying to get local time from mysql and use that to subtract with ruby time.
from_db = "2017-01-08 15:51:09" #this is from mysql database LOCALTIMESTAMP() function
on ruby,
local_time = Time.now.utc
local_timestamp = local_time.strftime("%Y-%m-%d %H:%M:%S") #converting to same format of mysql result
diff_time = local_timestamp - from_db # trying to subtract
but its failed and saying below error,
irb(main):001:0> from_db = "2017-01-08 15:45:09"
=> "2017-01-08 15:45:09"
irb(main):002:0> local_time = Time.now.utc
=> Sun Jan 08 15:52:45 UTC 2017
irb(main):003:0> local_timestamp = local_time.strftime("%Y-%m-%d %H:%M:%S")
=> "2017-01-08 15:52:45"
irb(main):004:0> diff_time = local_timestamp - from_db
NoMethodError: undefined method `-' for "2017-01-08 15:52:45":String
from (irb):4
from :0
irb(main):005:0>

You should parse time from the database and then do operations with the Time objects instead of strings:
require 'time'
from_db = Time.parse("2017-01-08 15:51:09").utc
local_time = Time.now.utc
diff_time = local_timestamp - from_db
=> 11667.904242 #seconds

Related

For loop with different number of iterations based on datetime

I am trying to get hourly data from a JSON file for a 34-month period. To do this I have created a daterange which I use in a nested loop to get data for each day for all 24 hours. This works fine.
However, because of daylight savings, there are only 23 daily observations on 3 occasions, the first being 2020-03-29. And therefore, I would like to loop only 23 iterations on this date since my loop crashes otherwise.
Below is my code. Right now it gets stuck on the date for SyntaxError: invalid syntax. But there is a high risk it will get stuck on something else when this is fixed.
Thank you.
start_date = date(2020, 1, 1)
end_date = date(2022, 11, 1)
def daterange(start_date, end_date):
for n in range(int((end_date - start_date).days)):
yield start_date + timedelta(n)
parsing_range_svk = []
for single_date in daterange(start_date, end_date):
single = single_date.strftime("%Y-%m-%d")
parsing_range_svk.append(single)
######################################
svk =[]
for i in parsing_range_svk:
data_json_svk = json.loads(urlopen("https://www.svk.se/services/controlroom/v2/situation?date={}&biddingArea=SE1".format(i)).read())
if i == '2020-03-29'
for i in range(23):
rows = data_json_svk['Data'][0]['data'][i]['y']
else:
for i in range(24):
rows = data_json_svk['Data'][0]['data'][i]['y']
svk.append(rows)
Don't check explicitly for a date, rather use list comprehension to get values you need (it will work correctly for 23/24 hours days):
from urllib.request import urlopen
from datetime import date, timedelta
start_date = date(2020, 1, 1)
end_date = date(2022, 11, 1)
def daterange(start_date, end_date):
for n in range(int((end_date - start_date).days)):
yield start_date + timedelta(n)
parsing_range_svk = []
for single_date in daterange(start_date, end_date):
single = single_date.strftime("%Y-%m-%d")
parsing_range_svk.append(single)
######################################
url = "https://www.svk.se/services/controlroom/v2/situation?date={}&biddingArea=SE1"
svk = []
for i in parsing_range_svk:
data_json_svk = json.loads(urlopen(url.format(i)).read())
svk.append([v["y"] for v in data_json_svk["Data"][0]["data"]])
print(svk)

Sorting with csv library, error says my dates don't match '%Y-%m-%d' format when it does

I'm trying to sort a CSV by date first then time second. With Pandas, it was easy by using df = df.sort_values(by=['Date', 'Time_UTC']). In the csv library, the code is (from here):
with open ('eqph_csv_29May2020_noF_5lines.csv') as file:
reader = csv.DictReader(file, delimiter=',')
date_sorted = sorted(reader, key=lambda Date: datetime.strptime('Date', '%Y-%m-%d'))
print(date_sorted)
The datetime documentation clearly says these codes are right. Here's a sample CSV (no delimiter):
Date Time_UTC Latitude Longitude
2020-05-28 05:17:31 16.63 120.43
2020-05-23 02:10:27 15.55 121.72
2020-05-20 12:45:07 5.27 126.11
2020-05-09 19:18:12 14.04 120.55
2020-04-10 18:45:49 5.65 126.54
csv.DictReader returns an iterator that yields a dict for each row in the csv file. To sort it on a column from each row, you need to specify that column in the sort function:
date_sorted = sorted(reader, key=lambda row: datetime.strptime(row['Date'], '%Y-%m-%d'))
To sort on both Date and Time_UTC, you could combine them into one string and convert that to a datetime:
date_sorted = sorted(reader, key=lambda row: datetime.strptime(row['Date'] + ' ' + row['Time_UTC'], '%Y-%m-%d %H:%M:%S'))
Nick's answer worked and used it to revise mine. I used csv.reader() instead.
lon,lat = [],[]
xy = zip(lon,lat)
with open ('eqph_csv_29May2020_noF_20lines.csv') as file:
reader = csv.reader(file, delimiter=',')
next(reader)
date_sorted = sorted(reader, key=lambda row: datetime.strptime
(row[0] + ' ' + row[1], '%Y-%m-%d %H:%M:%S'))
for row in date_sorted:
lon.append(float(row[2]))
lat.append(float(row[3]))
for i in xy:
print(i)
Result
(6.14, 126.2)
(14.09, 121.36)
(13.74, 120.9)
(6.65, 125.42)
(6.61, 125.26)
(5.49, 126.57)
(5.65, 125.61)
(11.33, 124.64)
(11.49, 124.42)
(15.0, 119.79) # 2020-03-19 06:33:00
(14.94, 120.17) # 2020-03-19 06:49:00
(6.7, 125.18)
(5.76, 125.14)
(9.22, 124.01)
(20.45, 122.12)
(5.65, 126.54)
(14.04, 120.55)
(5.27, 126.11)
(15.55, 121.72)
(16.63, 120.43)

In Rails, how to calculate durations between 2 UTC times read from mysql

I am using Rails 4. I've read 2 records(b1 and b2) from database. Both them have a column called build_start_time, which is defined as datetime type in Mysql. The build_start_time between b1 record and b2 record are like this:
2.0.0-p643 :021 > b1.build_start_time
=> Tue, 12 Aug 2014 18:23:31 UTC +00:00
2.0.0-p643 :012 > b2.build_start_time
=> Fri, 15 Aug 2014 10:07:18 UTC +00:00
How do I calculate the duration between them in Rails ? Does anybody have an idea?
The result should be something like:
b2.build_start_time - b1.build_start_time = 2 days 15 hours 53 minutes 47 seconds
Is this possible?
Assuming you can tolerate your answer being off by less than a second you could try using the to_i and ago methods:
def datetime_diff(datetime1, datetime2)
res = datetime1 <=> datetime2
if res == 0
# order doesn't matter in this case
min = datetime1
max = datetime2
elif res < 0
min = datetime1
max = datetime2
else
min = datetime2
max = datetime1
end
max.ago(min.to_i) # min.to_i returns min in seconds since the epoch
end
You figure out which time came first then you return the later of the two times x seconds ago, where x is the earlier time in seconds since the epoch. See http://api.rubyonrails.org/classes/DateTime.html#method-i-3C-3D-3E

Timestamp to Epoch in a CSV file with GAWK

Looking to convert human readable timestamps to epoch/Unix time within a CSV file using GAWK in preparation for loading into a MySQL DB.
Data Example:
{null};2013-11-26;Text & Device;Location;/file/path/to/;Tuesday, November 26 12:17 PM;1;1385845647
Looking to take column 6, Tuesday, November 26 12:17 PM, and convert to epoch time for storage. All times shown will be in EST format. I realize AWK is the tool for this, but can't quite seem to structure the command. Currently have:
cat FILE_IN.CSV | awk 'BEGIN {FS=OFS=";"}{$6=strftime("%s")} {print}'
However this returns:
{null};2013-11-26;Text & Device;Location;/file/path/to/;1385848848;1;1385845647
Presumably, this means I'm calling the current epoch time (1385848848 was current epoch at time of execution) and not asking strftime to convert the string; but I can't imagine another way to doing this.
What is the proper syntax for gawk/strftime to convert an existing timestamp to epoch?
Edit: This question seems loosely related to How do I use output from awk in another command?
$ cat file
{null};2013-11-26;Text & Device;Location;/file/path/to/;Tuesday, November 26 12:17 PM;1;1385845647
$ gawk 'BEGIN{FS=OFS=";"} {gsub(/-/," ",$2); $2=mktime($2" 0 0 0")}1' file
{null};1385445600;Text & Device;Location;/file/path/to/;Tuesday, November 26 12:17 PM;1;1385845647
Here's how to generally convert a date from any format to seconds since the epoch using your current format as an example and with comments to show the conversion process step by step:
$ cat tst.awk
function cvttime(t, a) {
split(t,a,/[,: ]+/)
# 2013 Tuesday, November 26 10:17 PM
# =>
# a[1] = "2013"
# a[2] = "Tuesday"
# a[3] = "November"
# a[4] = "26"
# a[5] = "10"
# a[6] = "17"
# a[7] = "PM"
if ( (a[7] == "PM") && (a[5] < 12) ) {
a[5] += 12
}
# => a[5] = "22"
a[3] = substr(a[3],1,3)
# => a[3] = "Nov"
match("JanFebMarAprMayJunJulAugSepOctNovDec",a[3])
a[3] = (RSTART+2)/3
# => a[3] = 11
return( mktime(a[1]" "a[3]" "a[4]" "a[5]" "a[6]" 0") )
}
BEGIN {
mdt ="Tuesday, November 26 10:17 PM"
secs = cvttime(2013" "mdt)
dt = strftime("%Y-%m-%d %H:%M:%S",secs)
print mdt ORS "\t-> " secs ORS "\t\t-> " dt
}
$ awk -f tst.awk
Tuesday, November 26 10:17 PM
-> 1385525820
-> 2013-11-26 22:17:00
I'm sure you can modify that for the current problem.
Also, if you don't have gawk you can write the cvttime() function as (borrowing #sputnik's date command string):
$ cat tst2.awk
function cvttime(t, cmd,secs) {
cmd = "date -d \"" t "\" '+%s'"
cmd | getline secs
close(cmd)
return secs
}
BEGIN {
mdt ="Tuesday, November 26 10:17 PM"
secs = cvttime(mdt)
dt = strftime("%Y-%m-%d %H:%M:%S",secs)
print mdt ORS "\t-> " secs ORS "\t\t-> " dt
}
$
$ awk -f tst2.awk
Tuesday, November 26 10:17 PM
-> 1385525820
-> 2013-11-26 22:17:00
I left srtftime() in there just to show that the secs was correct - replace with date as you see fit.
For the non-gawk version, you just need to figure out how to get the year into the input month/date/time string in a way that date understands if that maters to you - shouldn't be hard.
You can convert date to epoch with this snippet :
$ date -d 'Tuesday, November 26 12:17 PM' +%s
1385464620
So finally :
awk -F";" '{system("date -d \""$6"\" '+%s'")}' file
Thanks #Keiron for the snippet.

resultat BETWEEN is null

this is my jpql
#NamedQuery(name = "Subscribe.countByDate", query = "SELECT COUNT (s.idSubscribe) FROM Subscribe s WHERE s.dateInscription BETWEEN :dateS AND :dateF"),
this is my facade :
public Number subSexeDate(String v, Date dated, Date datef) {
Query query = em.createNamedQuery("Subscribe.countByDate");
//query.setParameter("sexe", v);
query.setParameter("dateS", dated, TemporalType.DATE);
query.setParameter("dateF", datef, TemporalType.DATE);
return (Number) query.getSingleResult();
}
this is my controller
public List<Number> subSexeDate() {
sexe();
Date d1= new Date(2008-01-07);
Date d2= new Date(2010-01-01);
List<Number> nb = new ArrayList<Number>();
for (String var : sexe()) {
nb.add(ejbFacade.subSexeDate("homme", d1, d2));
}
return nb;
}
the result is: [0, 0]
the real problem
Date d1 = new Date(2007-01-01); long x = d1.getTime(); long y = System.currentTimeMillis(); Date d2 = new Date(); d2.setTime(y); d1.setTime(x); List<Number> nb = new ArrayList<Number>(); for (String var : sexe()) { nb.add(ejbFacade.subSexeDate(var, d1, d2)); System.out.println(d1.toString()+"date2"+d2);}
but résult of system.out : Infos: Thu Jan 01 01:00:02 CET 1970date2Sun May 26 11:55:31 CEST 2013 –
I imagine the issue has to do with the way you are constructing your Date objects.
You are writing this:
Date d1= new Date(2008-01-07);
Which is the same as this:
long x = 2008 - 1 - 7;
Date d1 = new Date(x); // or new Date(2000L);
Which I suspect is not what you wanted. Use a DateFormat and parse your date string instead.