How to convert date string with specific locale to ISO format - javascript

I want to convert a date time string with a specific locale (locale defined in IANA format) to a Date object and print UTC time in ISO 8601 format. This code below works perfectly.
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', ()=>{
console.log(moment('2021-01-01T00:00:00').tz('America/New_York').toISOString());
});
</script>
The result is my console log shows 2021-01-01T05:00:00.000Z.
However, I want to achieve the same result without using any 3rd party libraries. I only want to use the browser's Javascript default objects/classes/apis etc... So I tried all of these but they all gave errors:
new Date("2021-01-01T00:00:00 America/New_York").toISOString();
(new Date("2021-01-01T00:00:00")).setLocale('America/New_York').toISOString();
(new Date("January 1, 2021 12:00:00 AM America/New_York").toISOString();
What is the correct way in javascript to convert a date string with a locale to ISO 8601 format without the use of javascript libraries like moment, luxon, etc...?
I need it to work in any Desktop version of Chrome, FireFox, Edge and Safari released after January 1, 2021 (support not needed for older versions).

Taking help from this StackOverflow answer, this can be done as follows. You were almost there. toLocaleString() is the method that you want. As the name suggests, it returns a string so it needs to be converted back into a date object. I think the bulkiness of doing this is why a lot of people prefer using a library like moment.
new Date(
new Date("2021-01-01T00:00:00")
.toLocaleString("en-US", {timeZone: "America/New_York"})
).toISOString();

You can use the vanilla javascript class called Intl.
const newDate = new Date();
console.log(new Intl.DateTimeFormat('en-us', { dateStyle: 'short', timeStyle: 'medium' }).format(newDate))
;

Related

Formatting a "YYYY-MM-DD" date string according to locale in Firefox

I'm looking at a semi-old codebase where the following code is used to format a date in YYYY-MM-DD format according to a user's locale:
new Date('2000-01-01').toLocaleDateString(navigator.language)
However, this doesn't work in Firefox because new Date('2000-01-01') returns a datetime (time is 00:00) in UTC while toLocaleDateString uses the user's local timezone, so the above will return "December 31, 1999" for a user in the US.
What is the sane, safe way of doing this across browsers? Is it possible to do without one or more extra dependency?
If you add a timestamp to that date string it seems to be initialized with that time in the local timezone:
new Date('2000-01-01T00:00:00');
I tried this in both Chrome and Firefox and it seems to work as you want. However, creating a date with a string should be avoided as there's no guarantee it works consistently across different browsers. It's better to break the date into its parts, parse it as numeric values and initialize the date that way:
var dateParts = '2000-01-01'.split('-').map(Number);
new Date(
dateParts[0],
dateParts[1] - 1, // month is base 0
dateParts[2]
);
Update: Turns out Safari assumes UTC even if appending a timestamp to the date string, so this is one more reason to parse it and initialize the date with numeric values, as this always uses the local timezone.

How can I create a Date from string, ignoring any timezone offsets?

The server uses +03:00 timezone. It offers me a date in this format: "2017-04-12T00:00:00+03:00"
I then create a new Date from this string:
options.startDate = new Date("2017-04-12T00:00:00+03:00")
But because on the client there is a different timezone, the result is actually:
Tue Apr 11 2017 23:00:00 GMT+0200 (Central Europe Daylight Time)
This brings me back one day and it's a big deal for me. Is there an elegant way to avoid this and create the same Date and Time in javascript, ignoring the timezone offset?
The date you have in options.startDate is the correct one. What you want is to display it as if you were from the same timezone as the server.
If you now server's timezone in the client script then I would considere using a library like moment.js. It would allow you to format date in the timezone you want (GMT for instance, or the one of the server).
Using both moment.js and its plugin timezone code could be :
moment("2017-04-12T00:00:00+03:00").tz("America/Los_Angeles").format();
You should never use the Date constructor or Date.parse to parse strings due to browsers differences. Even if you remove the timezone from the string and parse the remainder, e.g.
console.log( new Date('2017-04-12T00:00:00+03:00'.substr(0,19)).toString() );
you'll get different results in different browsers (e.g. Firefox and Safari).
If you don't want to use a library, use a simple function (see below). However, if you remove the timezone, the string will represent a different moment in time in each timezone with a different offset.
function parseISOIgnoreTimezone(s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2], b[3], b[4], b[5]);
}
console.log(parseISOIgnoreTimezone('2017-04-12T00:00:00+03:00').toString());
I really recommend #VictorDrouin his answer.
But if for some reason you don't want moment.js or fiddle around with it you can use this 'hack'
new Date("2017-04-12T00:00:00+03:00".match(/\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}/).pop());
What it does it matches the date against given regex date format, and then supplies it to the date parser which makes it a date.
Be careful when supplying it back to the database that you supply it back without timezone offset.
var stringdate = "2017-04-12T00:00:00+03:00";
function getDate(str_date) {
var matched = str_date.match(/\d{4}\-\d{2}\-\d{2}T\d{2}:\d{2}:\d{2}/).pop();
return new Date(matched);
}
console.log(getDate(stringdate));

Convert YYYY-MM-DD HH:MM:SS to different format in Javascript

I have a string in javascript as 2016-02-27 20:24:39 and I want to convert this as 27th Feb 08:24pm.
What is the easiest way to do in Javascript?
Checkout the JavaScript library called moment.js.
Since the default format for moment is ISO 8601 (YYYY-MM-DD HH:MM:SS), you don't need to tell moment how to parse the input String date (it defaults to ISO 8601), so you can simply write:
var now = "2016-02-27 20:24:39";
var formattedDate = moment(now).format("Do MMM HH:mma");
console.log(formattedDate);
Demo:
https://jsfiddle.net/gekd97dy/
More information about displaying in different formats can be read here:
http://momentjs.com/docs/#/displaying/
There is a non-standard Date method toLocaleFormat('%d-%b-%Y'). But appears to only work in Firefox for now.
Better use the date.format library (only 125 lines)
var date = new Date('2016-02-27 20:24:39');
dateFormat(date, "dS mmm, h:MMTT");

new Date() using Javascript in Safari

I'm having an issue using the new Date() function in Javascript. Safari is giving me an "Invalid Date" message.
I've created a short example at jsbin.
This appears to work on all other browsers, but not Safari. Any ideas on how I can take the value from an input (such as 2011-01-03) and turn it into a date object, while having it work properly in Safari?
Many thanks!
The date parsing behavior on JavaScript is implementation-dependent, the ISO8601 format was recently added to the ECMAScript 5th Edition Specification, but this is not yet supported by all implementations.
I would recommend you to parse it manually, for example:
function parseDate(input) {
var parts = input.match(/(\d+)/g);
return new Date(parts[0], parts[1]-1, parts[2]);
}
parseDate('2011-01-03'); // Mon Jan 03 2011 00:00:00
Basically the above function matches each date part and uses the Date constructor, to build a date object, note that the months argument needs to be 0-based (0=Jan, 1=Feb,...11=Dec).
The easy solution I tried
Download date.js from http://datejs.com/
Include in your file
then
var date = Date.parse('1970-01-12 00:00:00');
var formattedDate = date.toString('yyyy-MM-dd');
While #CMS's solution is probably superior, I found that using Date.parse('2011-01-13') is also a quick, working solution.
csnover has some progressive ISO 8601 Date enhancement code available on GitHub:
https://github.com/csnover/js-iso8601/blob/master/iso8601.js
Including his code should provide a temporary fix while the Safari team work toward a more complete ES5 implementation.

Java date format to JavaScript date format

I would like to be able to convert a Java date format string, e.g. dd/MM/yyyy (07/06/2009) to a JavaScript date format string, e.g. dd/mm/yy (07/06/2009).
Has anyone done this before, or got any idea where I might find some code that already does this?
Edit:
Thanks for all the replies but now I realize my mistake and possibly why so many of you were struggling to understand the question; JavaScript doesn't have a built in date formatting ability. I am using the jQuery UI datepicker and I have been setting its date format, assuming it would be calling a standard JS function at some point, not using its own library! When I googled for formatting strings I jumped straight to the tables of what letters could be used, skipping the bit at the beginning explaining how to use the script.
Anyway I'll have to go ahead and possibly write my own I guess, converting a Java date format string into a jQuery date format string (or as close as possible) - I am working on the i18n of our product and have created a java class that stores the preferred date format string used throughout the application, my intention was to also have the ability to supply any jsps with the format string that is equivalent in JS.
Thanks anyway.
If you just need to pass a date from Java to JavaScript, the best way to do it, I think, would be to convert the Java date to milliseconds using date.getTime(), create a JavaScript date initialized with this milliseconds value with new Date(milliseconds)and then format the date with the means of the JavaScript Date object, like: date.toLocaleString().
You could use my plugin jquery-dateFormat.
// Text
$.format.date("2009-12-18 10:54:50.546", "dd/MM/yyyy");
// HTML Object
$.format.date($("#spanDate").text(), "dd/MM/yyyy");
// Scriptlet
$.format.date("<%=java.util.Date().toString()%>", "dd/MM/yyyy");
// JSON
var obj = ajaxRequest();
$.format.date(obj.date, "dd/MM/yyyy");
A similar topic has been answered here:
Converting dates in JavaScript
I personally have found this to be a rather large pain and took the author's suggestion and used a library. As noted, jQuery datepicker has one that is a viable solution if you can afford the overhead of download for your application or already using it.
Check out moment.js! It's "A lightweight javascript date library for parsing, manipulating, and formatting dates". It is a really powerful little library.
Here's an example...
var today = moment(new Date());
today.format("MMMM D, YYYY h:m A"); // outputs "April 11, 2012 2:32 PM"
// in one line...
moment().format("MMMM D, YYYY h:m A"); // outputs "April 11, 2012 2:32 PM"
Here's another example...
var a = moment([2012, 2, 12, 15, 25, 50, 125]);
a.format("dddd, MMMM Do YYYY, h:mm:ss a"); // "Monday, March 12th 2012, 3:25:50 pm"
a.format("ddd, hA"); // "Mon, 3PM"
a.format("D/M/YYYY"); // "12/3/2012"
Also, its worth mentioning to checkout date.js. I think the two libraries complement each other.
This JavaScript library should be able to help you.
http://plugins.jquery.com/project/fIsForFormat
(I don't know why they have it as a jQuery Plugin, because it works standalone.)
You'd simply split the original formatted date into its individual elements and then create a new Date Object with those elements. Then, use this library's "Date.f()" method to output it into any format you could want.
For example:
var dateOld = "11/27/2010",
dateArr = date1.split("/"),
dateObj = new Date(dateArr[2], dateArr[0], dateArr[1]),
dateNew = dateObj.f("MMM d, yyyy");
document.write("Old Format: " + dateOld + "<br/>New Format: " + dateNew);
This works fine for me:
<%
Date date = Calendar.getInstance().getTime();
%>
<script>
var d = new Date(<%=date.getTime()%>);
alert(d);
</script>
I suggest you the MomentJS with this Plugin that allow you to convert a Java pattern to a JS pattern (MomentJS)
On Java Side
I recommend passing an Instant string which conforms to ISO 8601 standard.
import java.time.Instant;
class Main {
public static void main(String[] args) {
Instant instant = Instant.now();
// You can pass the following string to JavaScript
String strInstant = instant.toString();
System.out.println(strInstant);
// If the number of milliseconds from epoch is required
long millis = instant.toEpochMilli();
System.out.println(millis);
}
}
Output from a sample run:
2022-12-31T09:40:52.280726Z
1672479652280
ONLINE DEMO
Learn more about the modern Date-Time API from Trail: Date Time.
On JavaScript Side
Now, you can parse the ISO 8601 string on the JavaScript side simply by passing it as a parameter to Date constructor. You can also instantiate the Date object with the number of milliseconds from the epoch.
var date = new Date("2022-12-31T09:40:52.280726Z");
console.log(date.toISOString());
// Or if the number of milliseconds from epoch has been received
date = new Date(1672479652280);
console.log(date.toISOString());
The javascript code in this page implements some date functions and they "use the same format strings as the java.text.SimpleDateFormat class, with a few minor exceptions". It is not the very same as you want but it can be a good start point.
If you just want to format dates my date extensions will do that well - it also parses data formats and does a lot of date math/compares as well:
DP_DateExtensions Library
Not sure if it'll help, but I've found it invaluable in several projects.
If you are using java, take a look at the Simple Date Format class.

Categories

Resources