I am trying to create a graph containing a date histogram. Everything is working except when crossing the daylight savings period. Check the table below for an example, notice the problem with the line of October 31st. Does anyone know a way to overcome this problem and get buckets beginning on each first of the month. The inputs are dates without a time, so for every record the time is midnight.
April 1st 2013, 00:00:00.000 11499
May 1st 2013, 00:00:00.000 11850
June 1st 2013, 00:00:00.000 15992
July 1st 2013, 00:00:00.000 14215
August 1st 2013, 00:00:00.000 14178
September 1st 2013, 00:00:00.000 12739
October 1st 2013, 00:00:00.000 14133
October 31st 2013, 23:00:00.000 13653
November 30th 2013, 23:00:00.000 12537
December 31st 2013, 23:00:00.000 14040
Just to make things better to debug, this is the executed query:
{
"size": 0,
"query": {
"query_string": {
"query": "*",
"analyze_wildcard": true
}
},
"aggs": {
"2": {
"date_histogram": {
"field": "orderCreationDate",
"interval": "1M",
"pre_zone": "+02:00",
"pre_zone_adjust_large_interval": true,
"min_doc_count": 1
}
}
}
}
Related
As we all know, date parsing in Go has it's quirks*.
However, I have now come up against needing to parse a datetime string in CCYY-MM-DDThh:mm:ss[.sss...] to a valid date in Go.
This CCYY format is a format that seems to be ubiquitous in astronomy, essentially the CC is the current century, so although we're in 2022, the century is the 21st century, meaning the date in CCYY format would be 2122.
How do I parse a date string in this format, when we can't specify a coded layout?
Should I just parse in that format, and subtract one "century" e.g., 2106 becomes 2006 in the parsed datetime...?
Has anyone come up against this niche problem before?
*(I for one would never have been able to remember January 2nd, 3:04:05 PM of 2006, UTC-0700 if it wasn't the exact time of my birth! I got lucky)
The time package does not support parsing centuries. You have to handle it yourself.
Also note that a simple subtraction is not enough, as e.g. the 21st century takes place between January 1, 2001 and December 31, 2100 (the year may start with 20 or 21). If the year ends with 00, you do not have to subtract 100 years.
I would write a helper function to parse such dates:
func parse(s string) (t time.Time, err error) {
t, err = time.Parse("2006-01-02T15:04:05[.000]", s)
if err == nil && t.Year()%100 != 0 {
t = t.AddDate(-100, 0, 0)
}
return
}
Testing it:
fmt.Println(parse("2101-12-31T12:13:14[.123]"))
fmt.Println(parse("2122-10-29T12:13:14[.123]"))
fmt.Println(parse("2100-12-31T12:13:14[.123]"))
fmt.Println(parse("2201-12-31T12:13:14[.123]"))
Which outputs (try it on the Go Playground):
2001-12-31 12:13:14.123 +0000 UTC <nil>
2022-10-29 12:13:14.123 +0000 UTC <nil>
2100-12-31 12:13:14.123 +0000 UTC <nil>
2101-12-31 12:13:14.123 +0000 UTC <nil>
As for remembering the layout's time:
January 2, 15:04:05, 2006 (zone: -0700) is a common order in the US, and in this representation parts are in increasing numerical order: January is month 1, 15 hour is 3PM, year 2006 is 6. So the ordinals are 1, 2, 3, 4, 5, 6, 7.
I for one would never have been able to remember January 2nd, 3:04:05 PM of 2006, UTC-0700 if it wasn't the exact time of my birth! I got lucky.
The reason for the Go time package layout is that it is derived from the Unix (and Unix-like) date command format. For example, on Linux,
$ date
Fri Apr 15 08:20:43 AM EDT 2022
$
Now, count from left to right,
Month = 1
Day = 2
Hour = 3 (or 15 = 12 + 3)
Minute = 4
Second = 5
Year = 6
Note: Rob Pike is an author of The Unix Programming Environment
Trying to replace moment.js in my Angular application with Luxon to reduce bundle size.
I have come across a case where the two libraries produce a different output, and I am not sure why.
moment.js produces a date that is one hour ahead.
const activeToDateTimeString = '2014-08-06T13:07:04';
let foo1 = moment(activeToDateTimeString).utcOffset(-5, true);
let foo2 = DateTime.fromISO(activeToDateTimeString, {zone: 'America/New_York'}).setZone('America/New_York', { keepLocalTime: true });
let foo3 = DateTime.fromJSDate(new Date(activeToDateTimeString)).setZone('America/New_York', { keepLocalTime: true });
let foo4 = DateTime.fromISO(activeToDateTimeString).setZone('America/New_York', { keepLocalTime: true });
console.log(foo1.toDate());
console.log(foo2.toJSDate());
console.log(foo3.toJSDate());
console.log(foo4.toJSDate());
Output:
Wed Aug 06 2014 14:07:04 GMT-0400 (Eastern Daylight Time)
Wed Aug 06 2014 13:07:04 GMT-0400 (Eastern Daylight Time)
Wed Aug 06 2014 13:07:04 GMT-0400 (Eastern Daylight Time)
Wed Aug 06 2014 13:07:04 GMT-0400 (Eastern Daylight Time)
Why does moment.js produce a different output in this case?
let foo1 = moment(activeToDateTimeString).utcOffset(-4, true);
This would correct your code, but as you're moving to Luxon the daylight time changes won't effect you in the future.
Right now (19 mar 2020) New York is 4 hours behind UTC as from the 8th March 2020 it entered Eastern Daylight Time from Eastern Standard Time.
If New York was in Eastern Standard Time at the moment your code would output the same times.
In a Vuejs app, I currently have a button that is usable once a day. After it is clicked once, it is disabled until the following day. This works fine locally, but on heroku, the comparison does not seem to work.
Here is y date computed value in the vue component which returns true if the Act was created after 00:00 on the current date:
computed: {
...
actedToday() {
if (!!this.$store.getters.lastAct) {
let now = new Date();
console.log('this is now in actedToday computed: ', now);
let lastActDate = new Date(this.$store.getters.lastAct.created_at);
console.log('this is last act date in computed actedToday', this.$store.getters.lastAct.created_at);
console.log('was last Act today? ', lastActDate.getTime() > now.setHours(0,0,0,0));
return lastActDate.getTime() > now.setHours(0,0,0,0)
}
}
},
Here is what the console.log returns locally:
this is now in actedToday computed: Fri Oct 04 2019 15:20:24 GMT-0400 (Eastern Daylight Time)
ActButton.vue?0bb7:31 this is last act date in computed actedToday 2019-10-04T19:20:23.901Z
ActButton.vue?0bb7:32 was last Act today? true
And here is the analogous logs from the heroku app:
this is now in actedToday computed: Fri Oct 04 2019 15:21:18 GMT-0400 (Eastern Daylight Time)
ActButton.vue:31 this is last act date in computed actedToday 2019-10-04T03:30:22.266Z
ActButton.vue:32 was last Act today? false
In the first example, the comparison works as expected. In the second, although both dates are on the same day, the comparison returns false.
Your problem occurs due to different timezones. Your lastActDate is in Zulu-time (UTC, note the Z at the end) but your actedToday is in EDT. Using setHours(0,0,0,0) will give you the start of the day, but in the same timezone. Thus you have the following values:
//locally
now = Fri Oct 04 2019 15:20:24 GMT-0400 (Eastern Daylight Time)
now.setHours(0,0,0,0) = Fri Oct 04 2019 00:00:00 GMT-0400 (Eastern Daylight Time)
lastActDate = 2019-10-04T19:20:23.901Z = Fri Oct 04 2019 15:20:23.901 GMT-0400 (Eastern Daylight Time)
//heroku
now = Fri Oct 04 2019 15:21:18 GMT-0400 (Eastern Daylight Time)
now.setHours(0,0,0,0) = Fri Oct 04 2019 00:00:00 GMT-0400 (Eastern Daylight Time)
lastActDate = 2019-10-04T03:30:22.266Z = Fri Oct 03 2019 23:30:22.266 GMT-0400 (Eastern Daylight Time)
Thus heroku is right and your last action has not been "today". You should consider to use the same timezone in all of your dates.
I have a column having datetime objects in my table. I am using datatables plugin.
Upon trying to sort the particular column, it gets sorted with errors. Like,for the following dates
Aug. 20, 2018, 11:16 a.m.
Aug. 2, 2018, 12:25 p.m.
Aug. 4, 2018, 3:03 p.m.
I get the sorted result as
Aug. 2, 2018, 12:25 p.m.
Aug. 20, 2018, 11:16 a.m.
Aug. 4, 2018, 3:03 p.m.
What should be done to correct this?
As mentioned in jquery official document , you can only sort data for which format is mentioned.
and to sort date or time, you can add following lines to sort the date or time :
$('#example').dataTable( {
columnDefs: [
{ type: 'date-uk', targets: 0 }
]
} );
0 is the index of column. you can modify that based on your column index.
And you can change type date-uk to any other which is mentioned in document, if you receive data in same format.
OK so for example, today is Tuesday, Feb 02. Well the equivalent "Tuesday" from last year was on Feb 03.
How can I find this out programmatically?
Thanks!!
According to Google, there are 604,800,000 milliseconds in a week. That times 52 should give you the same day of the week a year later (right?).
For example:
var date:Date = new Date(2010, 1, 2);
trace(date);
date.setMilliseconds(date.milliseconds - 604800000 * 52);
trace(date);
Output:
Tue Feb 2 00:00:00 GMT-0800 2010
Tue Feb 3 00:00:00 GMT-0800 2009
Just my two cents. I don't like the idea, that the second answer assumes 52 weeks in a year, it will work for a single year, but is a solution to only this exact problem - eg. if you want to check the same thing moving back 10 years it won't work. I'd do it like this:
var today:Date = new Date();
// Here we store the day of the week
var currentDay:int = today.day;
trace (today);
const milisecondsInADay:uint = 1000*60*60*24;
// Here we move back a year, but we can just as well move back 10 years
// or 2 months
today.fullYear -= 1;
// Find the closest date that is the same day of the week as current day
today.time -= milisecondsInADay*(today.day-currentDay);
trace (today);
returns:
Tue Feb 2 21:13:18 GMT+0100 2010
Tue Feb 3 21:13:18 GMT+0100 2009