Comparing time from different timezones with moment.js - javascript

I have a Node.js server that triggers function based on timezones. Specifically, I'm using moment-timezone and from a fixed date and time input I need to trigger action at that same input but in different time zones.
So if I set in my server that the action should be triggered at 1:00 pm UK time and the user is in New York, I want the action to be triggered at 1:00 pm in New York.
That's what I am doing now:
exports.time_to_trigger = function(hour, date) {
var user_timezone = "Asia/Tokyo";
// create date object from date + hour strings
var dateObj = moment(date + hour, process.env.DATE_FORMAT + " HH:mm a");
// create offset
var max_value = moment(dateObj).add(3, 'minutes');
var low_value = moment(dateObj).add(-3, 'minutes');
console.log(max_value); // -> moment("2018-01-25T13:03:00.000")
console.log(low_value); // -> moment("2018-01-25T12:57:00.000")
// get the now value of the user timezone
var user_now = moment.tz(moment(), user_timezone);
console.log(user_now); // -> moment.parseZone("2018-01-24T13:01:00.038+09:00")
console.log(user_now.isAfter(low_value)); // -> false
console.log(user_now.isBefore(max_value)); // -> true
return (
user_now.isAfter(low_value) &&
user_now.isBefore(max_value)
)
}
As you can see from the comment, this is not working as the comparison with isAfter and isBefore take into consideration the time zone that I converted on purpose not to have this problem. How can I solve this?

Your issue is that you use timezone to get user_now but not to create dateObj. So dateObj is missing the timezone offset and your 2 dates are not comparable as you would wish.
To have all your dates on the same timezone:
// create date object from date + hour strings
var dateObj = moment.tz(date + hour, process.env.DATE_FORMAT + " HH:mm a", user_timezone);

Related

How do I compare a Date string in EST with a Date object in UTC?

I'm trying to compare this string 8/26/2019 6:53:13 which is in EST to a new Date() object to simply see if it's in the past. This works fine locally but on deployment heroku's new Date comes through in UTC format. So I had to do this hack
if(process.env.NODE_ENV){
timeSubmitted.setHours(timeSubmitted.getHours() + 5); // HACK but does work
}
I tried to get todays date and time in UTC format as an object not a string so I can compare it to other times in UTC format.
var date = new Date('2014-02-27T10:00:00')
//Thu Feb 27 2014 10:00:00 GMT-0500 (Eastern Standard Time) //this is an object
let d = moment.utc(new Date()).format()
//Does convert right now to a UTC time string, but then when I try convert it to an object
new Date(d)
//it goes back to EST
All together this does work, but isn't ideal because of the hardcoded number 5.
//SET DATE RANGE
const startDate = new Date();//This gets converted from EST to UTC
startDate.setMinutes(startDate.getMinutes() - 2); //Google spreadsheets saves minutes a little in the past
//startDate = new Date(startDate.getTime() + startDate.getTimezoneOffset() * 60000);
const endDate = new Date();
endDate.setDate(endDate.getDate() + 5)
console.log('startDate ' ,startDate,'endDate ',endDate)
rows.forEach(row=>{
//row.timestamp looks like this '8/26/2019 6:53:13' in EST
var date= row.timestamp.split(" ")[0].split('/')
var time=row.timestamp.split(" ")[1].split(':')
var timeSubmitted = new Date(date[2], date[0] - 1, date[1], time[0], time[1], time[2]); //So this is in EST
//but then when deploying to heroku i had to do this hack.
if(process.env.NODE_ENV){
timeSubmitted.setHours(timeSubmitted.getHours() + 5); // HACK -- It's the only way I could get this time to be in UTC/timeSubmitted = new Date(timeSubmitted.getTime() + timeSubmitted.getTimezoneOffset() * 60000);
}
console.log('timeSubmitted',typeof timeSubmitted, typeof startDate, timeSubmitted, startDate, timeSubmitted >= startDate, timeSubmitted < endDate)
if(timeSubmitted >= startDate && timeSubmitted < endDate){ //Within the date range so check if the names are in the roster
slackers = slackers.filter(function(a){return a.fullname !== row.whatsyourname})
}
})
messageSlackers(slackers, id)
Timezones are just a factor taken into consideration when generating a human-readable string from a date.
But a date is a point in time, regardless of timezones. Time doesn't know about timezones! Humans invented timezones.
You're probably stringising your Date objects in some manner that uses your local timezone by default (didn't show us this code). This doesn't matter.
Comparing two Dates works. Always. You don't have to worry about some hidden timezone component ruining it. Just compare your dates and you'll see that it works fine.
tl;dr: Dates are not in a "format". Dates are dates.

Convert UTC to standard date time format using javascript

How can I convert a UTC time into proper date - time format using Javascript?
This is what I want to do
var d = new Date("2014-01-01");
var new_d = d.toUTC(); // 1388534400000
var old_d = function(new_d){
// return "2014-01-01" // how can i get this?
}
Now How, can i get orignal date - 2014-01-01 from 1388534400000?
****Also, Please note that when i do this --- new Date(1388534400000); it gives date 1 day less.
That is, instead of giving Jan 01 2014, it gives Dec 31 2013. But, I want Jan 01 2014.****
Is there any method to do the opposite of toUTC() method?
// _________ For those whose toUTC() doesnt work
"toUTC" method works in console of my chrome
See screen shot below
When you pass a string containing hyphens to the Date constructor, it will treat that as UTC. And if you don't pass a time, it will consider it to be midnight. If you are in a time zone that is behind UTC (such as in most of the Americas), you will see the wrong local time conversion.
Here's a screenshot of my chrome dev console, so you can see what I mean
If I pass slashes instead:
Consider using moment.js - which will accept a format parameter that will help you avoid this issue.
Try using the following:
new Date(new_d);
The problem lies with the way you instantiate the Date.
Javascript interpretes the hyphens as an utc date, and slashes as local dates.
Giving the results that mark Explains.
var utcDate = new Date('2014-01-01') // returns a UTC date
var localDate = new Date('2014/01/01'); // Returns local date
But to translate a date back to your starting point string, you can do the following.
function toDateString(utcMillis){
var date = new Date(utcMillis);
d = date.getDate();
m = date.getMonth() +1;
y = date.getFullYear();
return y + '-' + addLeadingZero(m, 2) + '-' + addLeadingZero(d,2);
}
function addLeadingZero(n, length){
n = n+'';
if(n.length<length)
return addLeadingZero('0'+n, length--);
else
return n;
}
If you find yourself with a UTC date, you can still do this:
function toUTCDateString(utcMillis){
var date = new Date(utcMillis);
d = date.getUTCDate();
m = date.getUTCMonth() +1;
y = date.getUTCFullYear();
return y + '-' + addLeadingZero(m, 2) + '-' + addLeadingZero(d,2);
}
To play around with it, and see it for yourself, see this Fiddle:

Convert milliseconds into date in different timezones

How to convert milliseconds in mm/dd/yyyy in different timezones.
I have a datepicker, when I press save, it saves the date in millisecond.
The saved millisecond should display date according to timezone date.
My Code:
var millisecond=1378792800000;
var date=new Date(millisecond);
var date_month = date.getMonth() + 1;
display_date = date_month + "/" + date.getDate() + "/" + date.getFullYear();
The date is differ in different timezones
When my timezone is India GMT then it is 09/10/2013
and when I change my timezone to US Mountain it change to 09/09/2013.
So how can I handle different timezone in javascript.
I would suggest using a third party script such as moment.js to make your life easier
Here is an example: http://jsfiddle.net/cyxgJ/
var ms = 1378792800000;
var date = new moment(ms);
// see <http://momentjs.com/docs/#/manipulating/timezone-offset/>
date = date.zone(120);
document.body.innerHTML = date;

Acrobat Javascript Dates

I have a text field that displays the date in mmmm d, yyyy (called 'Expiry Date') and I am trying to make three smaller fields that display just the day (d), the month (m), and the year (yyyy) in each field.
I have tried to import the data into each field using this code:
var sField = 'Expiry Date'
and then i would custom format it just to "d", "m", or "yyyy" as appropriate. In the little formatting preview window it would show the desired output, but the fields would still be blank.
What is also odd is that it will only work with formatting that starts with the month.
The field that Im getting the first date is created from another calculation if that makes it any different. 'Expiry Date' gets it's data from a field called 'date'. Here is the code in which it assigns an expiry date 30 days after the value of 'date'
// define the value for the date field
var sField = 'Date'
// define the format of the date string
var cFormatDate = 'mm/dd/yyyy';
// define some time constants
var fSecond = 1000; // number of milliseconds in one second
var fMinute = 60 * fSecond; // number of milliseconds in a minute
var fHour = 60 * fMinute; // number of milliseconds in an hour
var fDay = 24 * fHour; //number of milliseconds in a day
// get the field object's string value
var fTodayDate = this.getField(sField).value;
// convert the string value into a date object
var oDate = util.scand(cFormatDate, fTodayDate);
// convert the date object to a value in milliseconds
var fDate = oDate.getTime();
// add 30 days to value using the number of milliseconds in a day
var fNewDate = fDate + (30 * fDay);
// convert computed date value to date object
var oNewDate = new Date(fNewDate);
// set the field's value to the date string for the date object
event.value = util.printd(cFormatDate, oNewDate);
Thanks in advance!!
I don't know anything about Acrobat, but assume its Date objects conform to ECMA-262. By far the best method of converting a date string to a date object is to parse it yourself, do not leave it up to the Date function/constructor or Date.parse.
From your post, it seems the date string is like October 17, 2012. There's a function below to help with that.
The best way to add whole days is to add them to the date, so given a date object:
// Create a new Date object
var now = new Date();
// Copy it
var then = new Date(now);
// Add 30 days
then.setDate(then.getDate() + 30);
Note that adding 30 to dates after 28 January (or 29 January in a leap year) will end up in March.
Edit
Date string parse function:
// Expects mmm d, yyyy e.g. October 17, 2012 or Oct 17, 2012
function parseDateString(s) {
var months={jan:0, feb:1, mar:2, apr:3, may:4, jun:5,
jul:6, aug:7, sep:8, oct:9, nov:10, dec:11};
var d = s.split(/\s/);
return new Date(d[2], months[d[0].toLowerCase().substring(0,3)], parseInt(d[1],10));
}
I may be over simplifying things, but if you have a date field (let's name it "DATE1") that has the full date in it.
Couldn't you just copy that field 3 time, assigning "DATE1" to the name for all three. This would take the date that you typed into the original Date field and duplicate it throughout the other three. Then just go into the field properties, ensure all 4 boxes are assigned the format "Date" -- and then on your 3 smaller boxes, assign them a Custom Date Option of "dd", "mm", or "yy" respectively?

UTC Times in JavaScript

I am trying to get the current UTC date to store in my database. My local time is 9:11 p.m. This equates to 1:11 a.m. UTC. When I look in my database, I notice that 1:11 p.m. is getting written to. I'm confused. In order to get the UTC time in JavaScript, I'm using the following code:
var currentDate = new Date();
var utcDate = Date.UTC(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate(), currentDate.getHours(), currentDate.getMinutes(), currentDate.getSeconds(), currentDate.getMilliseconds());
var result = new Date(utcDate);
What am I doing wrong?
A lttle searching turned out you can do this:
var now = new Date(),
utcDate = new Date(
now.getUTCFullYear(),
now.getUTCMonth(),
now.getUTCDate(),
now.getUTCHours(),
now.getUTCMinutes(),
now.getUTCSeconds()
);
Even shorter:
var utcDate = new Date(new Date().toUTCString().substr(0, 25));
How do you convert a JavaScript date to UTC?
It is a commonly used way, instead of creating a ISO8601 string, to get date and time of UTC out. Because if you use a string, then you'll not be able to use every single native methods of Date(), and some people might use regex for that, which is slower than native ways.
But if you are storing it in some kind of database like localstorage, a ISO8601 string is recommended because it can also save timezone offsets, but in your case every date is turned into UTC, so timezone really does not matter.
If you want the UTC time of a local date object, use the UTC methods to get it. All javascript date objects are local dates.
var date = new Date(); // date object in local timezone
If you want the UTC time, you can try the implementation dependent toUTCString method:
var UTCstring = date.toUTCString();
but I wouldn't trust that. If you want an ISO8601 string (which most databases want) in UTC time then:
var isoDate = date.getUTCFullYear() + '-' +
addZ((date.getUTCMonth()) + 1) + '-' +
addZ(date.getUTCDate()) + 'T' +
addZ(date.getUTCHours()) + ':' +
addZ(date.getUTCMinutes()) + ':' +
addZ(date.getUTCSeconds()) + 'Z';
where the addZ function is:
function addZ(n) {
return (n<10? '0' : '') + n;
}
Modify to suit.
Edit
To adjust a local date object to display the same time as UTC, just add the timezone offset:
function adjustToUTC(d) {
d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
return d;
}
alert(adjustToUTC(new Date())); // shows UTC time but will display local offset
Take care with the above. If you are say UTC+5hrs, then it will return a date object 5 hours earlier but still show "UTC+5"
A function to convert a UTC ISO8601 string to a local date object:
function fromUTCISOString(s) {
var b = s.split(/[-T:\.Z]/i);
var n= new Date(Date.UTC(b[0],b[1]-1,b[2],b[3],b[4],b[5]));
return n;
}
alert(fromUTCISOString('2012-05-21T14:32:12Z')); // local time displayed
var now = new Date();
var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);

Categories