Different time format returned by toLocaleTimeString - javascript

I am using Javascript code such as that shown below, and recently found that while Date.prototype.toLocaleTimeString() on one machine appends " GMT" or " BST" (depending on the time of year); on another machine, nothing is appended.
var m = new Date();
var time = m.toLocaleTimeString();
I use the returned string to create a log file, and would like the file names to have a canonical structure. I don't mind which of the two string formats is returned, as long as it is the same on both machines.
By the way, I also tried providing first and second arguments, such as m.toLocaleTimeString('en-gb', { hour: '2-digit', minute: '2-digit', second: '2-digit' }), or m.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' }), but then the seconds are no longer included in the returned string.

You could create a custom format function for your logs, using the Date.getHours(), getMinutes() etc.
This should be consistent across platforms and would allow any customization to be added easily.
function formatTimestamp(date) {
const hms = [date.getHours(), date.getMinutes(), date.getSeconds()];
return hms.map(s => (s + '').padStart(2, '0')).join(':');
}
console.log('Timestamp:', formatTimestamp(new Date()));

The behavior you are seeing with the toLocaleTimeString() method is likely due to differences in the default time zone settings on the two machines. The method returns a string that represents the time in the current time zone, which can be different depending on the machine's settings.
You can use toUTCString() method to get a string representation of the date in UTC format, this will always return the same format, regardless of the machine's time zone settings.
var m = new Date();
var time = m.toUTCString();
Another approach, you can use moment.js library, this library will handle timezone and other time related issues, and it's very useful when you are working with dates and time, it will give you a consistent format across different environments.
var moment = require('moment');
var time = moment().format('HH:mm:ss');
The moment().format('HH:mm:ss') will give you the time in the format of HH:mm:ss and you can use this as your log file name.
Additionally, you can also set your machine's time zone to a specific value using the Intl.DateTimeFormat() method, this will help you to get the same format across different machines.
var m = new Date();
var options = {timeZone: 'UTC', hour: '2-digit', minute: '2-digit', second: '2-digit'};
var time = new Intl.DateTimeFormat('en-GB', options).format(m);
This will give you the time formatted to 'en-GB' time zone and with the hour, minute and second digits.

Related

Convert Only Time to The Relevent Timezone

I am using moment js to get only the UTC time.
const time = moment().utc().format('HH:mm:ss');
example output is like this - "07:57:49"
I want to change this time value to relevant timezone value.
const americaTime = moment(time).tz("America/Los_Angeles").format();
But there is an warning saying - "Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged. Is there any alternative way to overcome this issue ?
do this
let time = moment().utc().tz("America/Los_Angeles").format('HH:mm:ss');
You can also display the time UTC, or in any IANA timezone with vanilla JS, using Date.toLocaleTimeString():
let dt = new Date();
const timeZones = ['UTC', 'America/Los_Angeles', 'America/New_York'];
console.log('Time zone'.padEnd(20), 'Current time')
for(let timeZone of timeZones) {
console.log(timeZone.padEnd(20), dt.toLocaleTimeString('en', { timeZone, hourCycle: 'h24', hour: '2-digit', minute: '2-digit', second: '2-digit' }));
}
.as-console-wrapper { max-height: 100% !important; }
const time = moment().utc().format('HH:mm:ss');
moment(time,'HH:mm:ss').tz("America/Los_Angeles").format();
You need to specify the format HH:mm:ss in the second param, momentjs throws this error because it is unable to parse the input without the format!

Convert time from utc to local time js

I need to take an hour and convert it to local time as such :
const dataDate = '07:08'
const utcDate = new Date(dataDate);
console.log(utcDate)
there are a few problems with my approach
this only works if i add a date too
this converts to utc
I need to only convert the hour to local time, I also need to parse it to something like this :
[parseInt(hour), 0, 0, 0].map(function (x) { return parseInt(x, 10); })
To give more context, I need to create a shareable calendar with a specific schedule, and the user can set the specific hours for some event to be displayed.
If you have access to the full date
Considering your use-case is that of a shareable calendar, I'm assuming you
have access to the full UTC date. If that's not the case, skip to the next
section.
// The important thing is getting a `Date` object. The timezone in the timestamp
// doesn't really matter at this point. It will be handled internally anyway.
const date = new Date("2011-11-11T07:08:00Z");
Once you have the date object, if all you really want to get is the hour,
you can do so with the methods below. But note that you should probably use the same method for getting not only the hours, but any part of the date or time throughout your application.
const utcHour = date.getUTCHours(); //> 7
// For the hour according to the timezone configured in the RUNTIME
// environment (e.g. the user's browser, if running on the client side):
const runtimeHour = date.getHours(); //> 8 (depends on the runtime timezone)
// For an arbitrary timezone, in case you have the user's timezone stored in
// a config you could use the `.toLocaleTimeString()` method.
// Note that this method is VERY slow (~6000 times slower than `.getHours()`
// for example in a quick benchmark I ran in my machine on Node 16). You
// should probably be careful about how often this is being called (e.g. in
// loops or in a frontend component that is frequently updated/rendered).
const tzHour = Number(date.toLocaleTimeString("en", {
hour: "numeric", // omit minutes and seconds
hour12: false, // force it to be 0-23
timeZone: "America/Sao_Paulo" // set the user's timezone
})); //> 5
Which one you should use really depends on your exact implementation. You might also want to check this answer that further explains how time zones are handled by Date.
NOTE: the .toLocaleTimeString() method depends on the
Intl.DateTimeFormat API. Check Date.prototype.toLocaleTimeString() at MDN
for a compatibility table.
Note about manually calculating time offsets
You need the date in order to reliably adjust the time.
If you don't have the date for some reason, you could do so but that would
mean quite some work and it would never really be reliable, as you would not be
able to factor in Daylight Saving Time adjustments, for example.
Also keep in mind that some timezones operate on fractions of an hour:
+XX30: Asia/Tehran, Asia/Kabul, Australia/Adelaide...
+XX45: Australia/Eucla
Australia/Lord_Howe has a Daylight Saving Time adjustment of 30 mins;
Depending on the requirements of your application, calculating this manually
might not be as simple as you expect. I would recommend to delegate these
calculations to the internal Date implementation (as shown in the previous section) instead of trying to adjust the time manually (keep in mind you would have to handle overflows from min → hour → day → month → year).
About parsing the time string
As for the parsing of the time string, you mentioned in your question, you could do something like:
const rawTime = "07:08";
const [hour, minutes, seconds = 0] = rawTime.split(":").map(Number); //> [7, 8, 0]
// or if you only care about the hours
const hour = Number(rawTime.split(":", 1)); //> 7
// or you could also use a quirk of `parseInt()`, as it ignores everything
// starting at the first non-numeric character:
const hour = parseInt(rawTime); //> 7
If you instantiate a new date with new Date() the retuned value is current date/time in UTC timezone.
You can then set a specific hour/minute to that using Date.setHours() and Date.setMinutes().
Finally you can convert that UTC date to local date via Date.toLocaleDateString()
So I would do something like this for your case:
const date = new Date();
const [hour, minute] = '7:28'.split(':')
const options = {
year: 'numeric',
month: 'long',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
};
date.setHours(hour);
date.setMinutes(minute);
console.log(date.toLocaleDateString('en-US', options));

Formatted JavaScript Date is one day behind [duplicate]

This question already has answers here:
Why does Date.parse give incorrect results?
(11 answers)
Closed 2 years ago.
I have a date: yyyy-mm-dd that I am formatting using the International DateTimeFormat like this:
const formatter = new Intl.DateTimeFormat("en-US", { month: '2-digit', day: '2-digit', year: 'numeric', timeZone:'America/Denver'});
// GiVES SAME RESULTS AS ABOVE
//const formatter = new Intl.DateTimeFormat("en-US", { month: '2-digit', day: '2-digit', year: 'numeric'});
//const formatter = new Intl.DateTimeFormat("default" , { month: '2-digit', day: '2-digit', year: 'numeric'});
let date = "2020-03-19"
return formatter.format(Date.parse(date));
//returns 03/18/2020 which is one day behind
I've tried this with and without the timeZone attribute. How can I fix this?
The ECMAScript Date Time String Format defines formats for both date-time forms as well as date-only forms. These are used by the Date.parse function and the Date constructor when a string is passed. Behavior for those functions is defined in the docs for the Date.parse function, which contain the following statement:
... When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.
Thus, when you call Date.parse('2020-03-19') the defined behavior is to treat that as UTC, not as local time. (This deviates from ISO 8601.)
To change this behavior, append a time string or a time+offset string.
For example, if you want to parse the time in the local computer's time zone:
Date.parse('2020-03-19T00:00:00.000')
Or, if you want to parse in a particular time zone and know the correct offset for the given timestamp in that time zone:
Date.parse('2020-03-19T00:00:00.000-05:00')
Often one doesn't know the offset, but does know the IANA time zone identifiers (such as 'America/Chicago'). Unfortunately, ECMAScript doesn't currently have the capability to parse in a named time zone yet. That capability will be possible if/when the TC39 Temporal proposal is adopted. Until then, you could use a library such as Luxon to perform such an action. For example:
luxon.DateTime.fromISO('2020-03-19', { zone: 'America/Chicago' }).toString()
//=> "2020-03-19T00:00:00.000-05:00"
Date.parse("2020-03-19") indicates 2020-03-19 00:00:00 GMT, so it will be 2020-03-18 for America/Denver, which will be 2020-03-18 17:00:00 America/Denver
const formatter1 = new Intl.DateTimeFormat("en-US", { month: '2-digit', day: '2-digit', year: 'numeric', timeZone:'America/Denver'});
const formatter2 = new Intl.DateTimeFormat("en-US", { month: '2-digit', day: '2-digit', year: 'numeric'});
let date = "2020-03-19"
console.log(formatter1.format(Date.parse(date)));
console.log(formatter2.format(Date.parse(date)));
You have added time zone, because of that it convert date into that time zone and because of the zone it can be 1 day behind or next day.

How to parse moment into specific timezone from moment.unix()

I have an initial value for a timestamp (created in User-1's timezone) I'm retrieving from firebase's firestore. the format this is in, is seconds in UTC from the Unix Epoch.
My goal is to take the initial timestamp value, and convert it to the timezone of the current user. if I use
moment.unix(initial_In_Seconds).format("H:mma") I get the correct initial time. Using .unix() is the only way I've been able to get the correct initial time. Now I need to convert it to a specific timezone. lets say "America/Denver" (the initial timezone is GMT -05:00)
I haven't been successful using moment.tz() in any of my amalgamations thus far.
I've tried:
moment.tz(moment.unix(initial_In_Seconds).format("H:mma"), "America/Denver")
let unix = moment.unix(initial_In_Seconds).format("H:mma");
let parsed = moment.tz(unix, "America/Denver");
How can this be parsed? Moment.js confuses me
If your timezone offset is specified using IANA representative locations, such as 'America/Denver', then you can likely use toLocaleString provided the locations aren't too obscure (i.e. aren't unsupported by ECMAScript implementations likely to run your code), e.g.
function timeValueWithTimezone(unixOffset, loc) {
let d = new Date(unixOffset * 1000);
return d.toLocaleString(void 0, {
hour12: true,
hour: 'numeric',
minute: '2-digit',
timeZone: loc
});
}
let timeValue = 1582090120;
let loc = 'America/Denver';
console.log('At your local time: ' +
new Date(timeValue * 1000).toLocaleString(void 0, {
hour12: true,
hour: 'numeric',
minute: '2-digit'
}));
console.log('Denver local time is: ' + timeValueWithTimezone(timeValue, loc));
further playing has yielded better results:
moment
.tz(moment.unix(props.navigation.state.params.time.start.seconds),'America/Denver')
.format('H:mma')
unfortunately for hours that are PM, it gives military time...and im interested in 12hr format...
EDIT: changes -> .format('h:mma') yields 12hr format

Get time of specific timezone [duplicate]

This question already has answers here:
Convert date to another timezone in JavaScript
(34 answers)
Closed 6 years ago.
The community reviewed whether to reopen this question 11 months ago and left it closed:
Duplicate This question has been answered, is not unique, and doesn’t differentiate itself from another question.
I am using a JavaScript Date class & trying to get the current date using getDate() method. But obviously it is loading system date & time. I am running the code from India but I want to get the date & time of UK using the same method. How can I do that ?
If you know the UTC offset then you can pass it and get the time using the following function:
function calcTime(city, offset) {
// create Date object for current location
var d = new Date();
// convert to msec
// subtract local time zone offset
// get UTC time in msec
var utc = d.getTime() + (d.getTimezoneOffset() * 60000);
// create new Date object for different city
// using supplied offset
var nd = new Date(utc + (3600000*offset));
// return time as a string
return "The local time for city"+ city +" is "+ nd.toLocaleString();
}
alert(calcTime('Bombay', '+5.5'));
Taken from: Convert Local Time to Another
You could use Intl.DateTimeFormat.
let options = {
timeZone: 'Europe/London',
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
},
formatter = new Intl.DateTimeFormat([], options);
console.log(formatter.format(new Date()));
Alternatively, if you're formatting just once instead of bulk use Date.prototype.toLocaleDateString().
(new Date()).toLocaleString([], options)
Unfortunately browsers are not required to understand timezones other than UTC, so try these blocks and figure out an alternative in case it fails, for example fetch the timezone offset from a server.
One way to do this is to use getLocaleString, like this:
Create a date object:
date = new Date(0)
If you are in Berlin, this should convert to this string:
Thu Jan 01 1970 01:00:00 GMT+0100 (CET)
Get the hours in Athens:
date.toLocaleString('de-DE', {hour: '2-digit', hour12: false, timeZone: 'Europe/Athens' })
'02'
Get the hours in Shanghai:
date.toLocaleString('de-DE', {hour: '2-digit', hour12: false, timeZone: 'Asia/Shanghai' })
'08'
You can use getUTCDate() and the related getUTC...() methods to access a time based off UTC time, and then convert.
If you wish, you can use valueOf(), which returns the number of seconds, in UTC, since the Unix epoch, and work with that, but it's likely going to be much more involved.
This is Correct way to get ##
function getTime(offset)
{
var d = new Date();
localTime = d.getTime();
localOffset = d.getTimezoneOffset() * 60000;
// obtain UTC time in msec
utc = localTime + localOffset;
// create new Date object for different city
// using supplied offset
var nd = new Date(utc + (3600000*offset));
//nd = 3600000 + nd;
utc = new Date(utc);
// return time as a string
$("#local").html(nd.toLocaleString());
$("#utc").html(utc.toLocaleString());
}
If it's really important that you have the correct date and time; it's best to have a service on your server (which you of course have running in UTC) that returns the time. You can then create a new Date on the client and compare the values and if necessary adjust all dates with the offset from the server time.
Why do this? I've had bug reports that was hard to reproduce because I could not find the error messages in the server log, until I noticed that the bug report was mailed two days after I'd received it. You can probably trust the browser to correctly handle time-zone conversion when being sent a UTC timestamp, but you obviously cannot trust the users to have their system clock correctly set. (If the users have their timezone incorrectly set too, there is not really any solution; other than printing the current server time in "local" time)
before you get too excited this was written in 2011
if I were to do this these days I would use Intl.DateTimeFormat. Here is a link to give you an idea of what type of support this had in 2011
original answer now (very) outdated
Date.getTimezoneOffset()
The getTimezoneOffset() method returns the time difference between Greenwich Mean Time (GMT) and local time, in minutes.
For example, If your time zone is GMT+2, -120 will be returned.
Note: This method is always used in conjunction with a Date object.
var d = new Date()
var gmtHours = -d.getTimezoneOffset()/60;
document.write("The local time zone is: GMT " + gmtHours);
//output:The local time zone is: GMT 11
The .getTimezoneOffset() method should work. This will get the time between your time zone and GMT. You can then calculate to whatever you want.
short answer from client-side: NO, you have to get it from the server side.

Categories