date-fns/format always takes local timezone - javascript

From below code:
const dateString = '1994-09-15T12:00:00-03:00';
const parsedDate = parseISO(dateString)
const dateFormat = 'MM-dd-yyyy HH:mm:ss xxx'
console.log(format(parsedDate, dateFormat, { }))
I expect:
09-15-1994 20:30:00 -03:00 But i get 09-15-1994 20:30:00 +05:30 as my local timezone is +05:30
What am i missing here?

The parseDate() creates a date based on GMT, e.g. is adjusted by 3h based on your input '1994-09-15T12:00:00-03:00'.
The format() function with xxx formats local time without the Z, such as -08:00, +05:30, +00:00. If you want to format with GMT string, specify OOOO, which will give you something like GMT-08:00, GMT+05:30, or GMT+00:00, which again has the offset adjusted based on your browser's time zone.
See Time-Zones docs below if you want to format to a time zone other than your browser's one, such as GMT-03:00.
Docs:
ISO 8601: https://en.wikipedia.org/wiki/ISO_8601
parseDate(): https://date-fns.org/v2.29.2/docs/parseISO
format(): https://date-fns.org/v2.29.2/docs/format
Time-Zones: https://date-fns.org/v2.29.2/docs/Time-Zones

Related

Set CET timezone with toISOString()

How do I change the MYSQL timestamp date to the JS date using toISOString () and setting the time-zone to CET?
This is what I use and it returns the following format "2021-02-251 15:27:20" which is what I want, only the time should be +1 hour "2021-02-251 16:27:20 ":
registration_date_customer.toISOString().replace(/T/, ' ').replace(/\..+/, '')
The time on the database is correct (16:27:20).
Does anyone know how to set the CET time-zone?
You can use Date.localeString() to format in the correct timeZone, the IANA timezone "Europe/Paris" is equivalent to CET. Using the "sv" locale will result in an ISO formatted string (Sweden uses ISO date formatting).
const registration_date_customer = new Date("2021-02-25 15:27:20Z");
console.log(registration_date_customer.toLocaleString("sv", { timeZone: "Europe/Paris"}));

How to convert utc timestamp to current time of another city?

I got timestamp utc of new york from weather api, want to display current time in New York but it gives output something like this 'UTC Sun Dec 01 2019 05:00:00 GMT+0530 (India Standard Time)'.
See the code for reference
// Code 1
//I get timestamp_utc when console.log(data)
//timestamp_utc: "2019-12-01T05:00:00"
const utc = new Date(data.timestamp_utc)
console.log('UTC', utc)
// UTC Sun Dec 01 2019 05:00:00 GMT+0530 (India Standard Time)
// Code 2
// Another code for getting current time but, failed
var usaTime = new Date().toLocaleString("en-US", {timeZone: timezone}); // Here timezone is from props
console.log('USA time: '+usaTime) // USA time: 12/1/2019, 4:59:58 AM
I also have timezone data getting from weather API. My aim is to get current time based on timezone or utc timestamp. As you can see both my trials are unsuccessful. Expected output is 6:39 PM which is now current time in New York. Is there any good solution?
Let me start with your 'code 2'. This is the same as what you wrote but with the timezone filled in...
const timezone = "America/New_York";
const usaTime = new Date().toLocaleString( "en-US", { timeZone: timezone});
console.log( 'usaTime =', usaTime );
For me this works. I get the current time in NY formatted correctly for USA. I'm not sure why yours did not work but I wonder what you specified for the timezone string.
I also a bit puzzled by your 'Code 1'. The 'new Date()' that you created is being converted to a string and then printed by your console.log statement, but this should result in a ISO 8601 string and you seem to be getting a locale string (the date format).
Though the example string you gave is in ISO 8601 format, it is not explicitly UTC because it does not end with a Z, nor does it end with a time zone offset such as +00:00. Thus when you parse it with the Date constructor, it is interpreted as local time. You can fix this by adding the Z yourself (assuming the timestamp_utc field is consistently a string in that format):
// timestamp_utc: "2019-12-01T05:00:00"
const utc = new Date(data.timestamp_utc + 'Z'); // adding the Z forces parsing as UTC
Now you have a Date object. However, if you just pass it to console.log, the output you see is implementation dependent. You will either see the local time in the same format you'd get by calling toString, or you will see the UTC time in the same format you'd get by calling toISOString.
To get the time in a different time zone, now you can call toLocaleString and pass the timeZone option. This assumes that the time zone is a valid IANA time zone identifier, and that the environment where the code is running fully supports the time zone features of the ECMAScript Internationalization Specification (ECMA-402). This is indeed the case with most modern browsers, but you will not get correct output in older browsers such as Internet Explorer.
const usEasternTime = utc.toLocaleString("en-US", {timeZone: 'America/New_York'});
Lastly from your variable name usaTime, I think perhaps you might be under the assumption that the US has a single time zone, but it does not. You will need to pass the correct time zone identifier. See the list on Wikipedia.
Define the time zones of origin ($ sourceDate) and destination (to convert).
$sourceTimeZone = 'utc';
$targetTimeZone = 'America/Bogota';
Separate the components of the date of origin that is in the format ‘m / d / y h: m: s’.
list($month, $day, $year, $hours, $minutes, $seconds) = sscanf($sourceDate, "%d/%d/%d %d:%d:%f");
Build the DateTime object indicating the date and time zone in which it is located.
$datetime = new DateTime("{$year}-{$month}-{$day} {$hours}:{$minutes}:{$seconds}",
new DateTimeZone($sourceTimeZone));
Modify the time zone of the DateTime to the destination time zone.
$datetime -> setTimezone(new DateTimeZone($targetTimeZone));
Get the components of the new date with the modified time zone.
list($month2, $day2, $year2, $hours2, $minutes2, $seconds2) = sscanf($datetime -> format(‘m/d/Y H:i:s’), “%d/%d/%d %d:%d:%f”);
Show the dates.
echo "En {$sourceTimeZone}: {$day}/{$month}/{$year} {$hours}:{$minutes}:{$seconds}<br/>";
echo "En {$targetTimeZone}: {$day2}/{$month2}/{$year2} {$hours2}:{$minutes2}:{$seconds2}<br/>";
PD: For JavaScript this can help you Convert time to different timezone with jQuery

Convert utc time into local time of specifc format

I have a date string of format dd.MM.yyyy HH:mm:ss but its UTC which I want to convert to local. How can I do it using moment library?
const dateStr = '20.09.2018 16:12:37';
const format = 'dd.MM.yyyy HH:mm:ss';
// for local time of UTC +3.00 new date Str will be 20.09.2018 19:12:37
You have to use moment.utc(String, String) to parse your string using UTC mode
By default, moment parses and displays in local time.
If you want to parse or display a moment in UTC, you can use moment.utc() instead of moment()
Then you can use local() to convert it to local time:
Sets a flag on the original moment to use local time to display a moment instead of the original moment's time.
Please note that since you input dateStr is not in ISO 8601/RCF 2822 recognized format you have to specify format when parsing it. Morover moment tokens are case sensitive so you have to use uppercase YYYY instead of yyyy to parse years and uppercase DD to parse day of the month since lowercase dd stands for day of the week (Mon, Tue, etc).
Here a live sample:
const dateStr = '20.09.2018 16:12:37';
const format = 'DD.MM.YYYY HH:mm:ss';
console.log(moment.utc(dateStr, format).local().format(format));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script>
Have a look at Local vs UTC vs Offset guide to better understand how UTC and locale mode work in momentjs.
To convert from UTC to Local you need to use moment.local() method
const dateStr = '20.09.2018 16:12:37';
const format = 'DD.MM.YYYY HH:mm:ss';
var newDate = moment.utc().format(format);
var temp= moment.utc(newDate, format);
var local = moment(temp).local().format(format);
More info on the official Documentation

Converting Central Time date to ISO string in current timezone

I have a date I know is stored in Central Time. It has the following format: 2017-11-19T23:39:35.280000. I want to turn this into an ISO-formatted date in the current timezone. I got it to work when simply creating a new Date() -- but then when I subsequently call .toISOString(), it goes haywire. Here's the code:
function convertCentralToLocal() {
const centralOffset = 360;
const dateInCentralMs = new Date('2017-11-19T23:39:35.280000').getTime();
const now = new Date();
const localOffset = now.getTimezoneOffset();
// this works: Sun Nov 19 2017 23:39:35 GMT-0600 (CST)
const d = new Date(dateInCentralMs + ((centralOffset - localOffset) * 60000));
// this seems to give the date six hours off: 2017-11-20T05:39:35.280Z
const iso = d.toISOString();
}
Is it an issue with GMT? I'm feeling lost.
It's true that ISO 8601 doesn't define a fixed timezone to represent the Date/Time, but it does define symbols to represent the timezone and a few date/time formats as well:
Date and Time Formats
TZD = time zone designator (Z or +hh:mm or -hh:mm)
Date.prototype.toISOString()
At MDN you can read that the timezone will be always zero UTC offset:
The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset, as denoted by the suffix "Z".
It's a particularity from Date.toISOStringMethod. On the same way that a fixed format was chosen (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ), it had been chosen a specific timezone to ISO representation.
To workaround this particularity, you could implement the method toISOString() as shown in this link below or just use your own example.

Any way to parse a time string using Moment.js but ignore timezone info?

Given the volume of Timezone questions, I would have thought to be able to find the answer to this issue, but haven't had any success.
Is there a way using moment.js to parse an ISO-8601 string but have it parsed in my local timzeone? Essentially I want to ignore the timezone information that is supplied in the ISO string.
For example, if I am in EDT timezone:
var x = moment( "2012-12-31T00:00:00+0000" );
will give me:
"2012-12-30T19:00:00-5000"
I'm looking to ignore the timezone info and just have it give me a moment equivalent of "2012-12-31T00:00:00-5000" local time (EDT).
I don't think you really want to ignore the offset. That would ultimately just be replacing the offset you provided with one from your local time zone - and that would result in a completely different moment in time.
Perhaps you are just looking for a way to have a moment retain the time zone it was given? If so, then use the moment.parseZone function. For example:
var m = moment.parseZone("2012-12-31T00:00:00+0000");
var s = m.format(); // "2012-12-31T00:00:00+00:00"
You could also achieve this with moment.utc. The difference is that moment.parseZone will retain whatever offset you give it, while moment.utc will adjust to UTC if you give it a non-zero offset.
I solved this by supplying a format as the second argument, and using Moment's method of escaping characters, and wrapped square brackets around the timezone.
moment("2016-01-01T05:00:00-05:00", "YYYY-MM-DDTHH:mm:ss[Z]").startOf("hour").format()
This will still create moment objects using your local time zone, but it won't do any sort of auto-timezone calculation. So the above example will give you 5am regardless of timezone supplied.
I know I'm late to the party, I had the same question and my searches didn't bring me any closer. I broke down and read the documentation and there is an option in moment for a String + Format:
String + Format docs
moment(String, String);
moment(String, String, String);
moment(String, String, Boolean);
moment(String, String, String, Boolean);
and more words, then this:
Unless you specify a time zone offset, parsing a string will create a date in the current time zone.
moment("2010-10-20 4:30", "YYYY-MM-DD HH:mm"); // parsed as 4:30 local time
moment("2010-10-20 4:30 +0000", "YYYY-MM-DD HH:mm Z"); // parsed as 4:30 UTC
The part that gave me pause was the example that was used to parse local time omitted the +0000, which lead me to think the input string needed to have that removed, but it doesn't.
example:
var time = "2012-12-31T00:00:00+0000";
var x = moment(time); // Sun Dec 30 2012 19:00:00 GMT-0500
var y = moment(time,'YYYY-MM-DD'); //Mon Dec 31 2012 00:00:00 GMT-0500
You can ignore the browser's timezone completely by creating a new moment using moment.utc() instead of moment().
For example, if you are trying to work purely with a UTC date/time of the browser's current time but want to discard its timezone data, you can recreate the browser's current time into a UTC format using the following:
let nowWithTimezone = moment();
let nowInUtc = moment.utc(nowWithTimezone.format('MM/DD/YYYY HH:mm'), 'MM/DD/YYYY HH:mm');
Further documentation on moment.utc(): https://momentjs.com/docs/#/parsing/utc/
If you know for sure your input string is in the ISO-8601 format, you could just strip off the last 5 digits and use that in the Moment constructor.
var input = "2012-12-31T00:00:00+0000"
input = input.substring(0, input.length-5)
moment(input).toString()
> "Mon Dec 31 2012 00:00:00 GMT-0600"
There are valid reasons to do what the OP is asking for. The easiest way to do this with Moment is using its parseZone(date) method. No futzing around with string manipulation or multiple calls. It effectively parses the date string as though it were in the browser's local time zone.
This is difficult task to do with MomentJS, it will basically depend as well on your current timezone.
Documentation as well is vague for this specific task, the way I solved the issue on my side was by adding hours to the date before converting it to JSON format.
var dt = moment("Sun Sep 13 2015 00:00:00 GMT-0400", "ddd MMM DD YYYY HH:mm:ss GMT-0400", false);
var date = dt.add(2, 'hour').toJSON();
console.log(date); //2015-09-13T00:00:00.000Z
Momentjs default logic will format the given time with local timezone. To format original date, I wrote a function:
https://github.com/moment/moment/issues/2788#issuecomment-321950638
Use moment.parseZone to convert without taking into account the timezone.
const moment = require('moment')
const dateStr = '2020-07-21T10:00:00-09'
const date = moment.parseZone(dateStr)
console.log(date.format('MM-DD-YY HH:mm A')) // 07-21-20 10:00 AM
Try here link to docs
The best way is to use:
dt = moment("Wed Sep 16 2015 18:31:00 GMT-0400", "ddd MMM DD YYYY HH:mm:ss GMT-0400",true);
And to display convert again to desired timezone:
dt.utcOffset("-04:00").toString()
output > Wed Sep 16 2015 18:31:00 GMT-0400

Categories