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.
Related
I have this in c#:
var date = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
and the result is like this:
date = "Tue, 27 Dec 2022 13:30:35 GMT";
I want to have this result in pre-request of postman to pass this variable as date.
But this command doesn't give me the exact result:
var date = new Date();
//result: Tue Dec 27 2022 16:26:00 GMT+0100 (Central European Standard Time)
As I'm using this date variable for encryption, it's important to have it in the special format I have in c#.
Do you have any idea how can I have this result in postman?
To display time, you can use momentjs, that's already included in postman. The cons is it doesn't support timezone, so the code would be:
const moment = require('moment')
let datetime = moment().format("ddd, DD MMM YYYY HH:mm:ss ") + "GMT"
//Wed, 28 Dec 2022 08:08:36 GMT
Using reg expression in pre-request section
var date = new Date();
// Tue Dec 27 2022 12:10:39 GMT-0500 (Eastern Standard Time)
console.log(date);
let match = /(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d{1,2})\s+(\d{4})\s+(\d{2}|\d{1})\:(\d{2})\:(\d{2})\s([a-zA-Z]{3})/.exec(date);
// 0: "Tue Dec 27 2022 12:10:39 GMT"
// 1: "Tue"
// 2: "Dec"
// 3: "27"
// 4: "2022"
// 5: "12"
// 6: "10"
// 7: "39"
// 8: "GMT"
// newDate = "Tue, 27 Dec 2022 13:30:39 GMT";
newDate = `${match[1]}, ${match[3]} ${match[2]} ${match[4]} ${match[5]}:${match[6]}:${match[7]} ${match[8]}`
console.log(newDate);
Result in console
Tue Dec 27 2022 12:22:39 GMT-0500 (Eastern Standard Time)
Tue, 27 Dec 2022 12:22:39 GMT
Test string set in https://regex101.com/
Regular Expression
(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s+(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+(\d{1,2})\s+(\d{4})\s+(\d{2}|\d{1})\:(\d{2})\:(\d{2})\s([a-zA-Z]{3})
In Reg Expression Visualization https://regexper.com/
So here is how i setup my datepicker
$('#picker').datepicker({
format: 'yyyy-mm-dd',
multidate: true
});
and then here is how i showing the result
$('#picker').on('changeDate', function(event) {
console.log( $('#picker').datepicker("getDates"));
});
here is the result from console
[Tue Jun 02 2020 00:00:00 GMT+0700 (Waktu Indonesia Barat), Wed Jun 10 2020 00:00:00 GMT+0700 (Waktu Indonesia Barat), Wed Jun 17 2020 00:00:00 GMT+0700 (Waktu Indonesia Barat)]
How can i make it to yyyy-mm-dd format ?
So here is how i fix it
$('#picker').datepicker("getFormattedDate")
maybe it will help others
Give moment.js a try. It is a very powerful tool not just only to format Date objects, but to manipulate them and make custom validations.
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 can't figure out what I am doing wrong here.
Passing in a string to moment, with the format and calling .toDate().
toDate() ends up returning a time that is off by 1 hour
moment("2015-11-19T18:34:00-07:00", "YYYY-MM-DDTHH:mm:ssZ").toDate()
> Thu Nov 19 2015 17:34:00 GMT-0800 (PST)
The time should be 18:34, not 17:34. The timezone is showing -08, when it should be showing -07
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