Javascript toLocalDateString outputs different format on windows vs mac - javascript

I'm using Javascript's toLocalDateString method to get the date of the user on their local system time.
However the output format of the function is different across windows and mac (using chrome browsers on both):
On Windows
On Mac
As you can see on windows we get format m-dd-yyyy whereas on mac it's dd-mm-yyyy. This is causing issues in my code as I need to display it in a common format using substr on the resulting output and fetching year, date and month separately.
Is there any way to force this to output in one particular format only or is there any other reliable way to get system's local date (I only need date not the time)

You will have to pass locals argument as below:
// US English uses month-day-year order
console.log(date.toLocaleDateString('en-US'))
// British English uses day-month-year order
console.log(date.toLocaleDateString('en-GB'))
Check reference link -
toLocaleDateString

There is no guarantee whatsoever how the output of toLocaleDateString() will look on a particular browser on a particular system. So if you need a specific format, you must either create it yourself or use some library.
If you just need separate year, day and month of the current date, why not just use the respective methods on the Date() object?
const today = new Date();
const year = today.getFullYear();
const month = today.getMonth() +1; //month count is 0-based
const day = today.getDate();

var date= new Date();
var formatDate;
if(navigator.appVersion.indexOf("Win") != -1){
formatDate= date.toLocaleDateString('en-GB');
}
else{
formatDate= date.toLocaleDateString();
}
console.log(formatDate);

Related

How can I get timezone name from date string in javascript in node environment? [duplicate]

I know how to get the timezone offset, but what I need is the ability to detect something like "America/New York." Is that even possible from JavaScript or is that something I am going to have to guestimate based on the offset?
The Internationalization API supports getting the user timezone, and is supported in all current browsers.
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)
Keep in mind that on some older browser versions that support the Internationalization API, the timeZone property is set to undefined rather than the user’s timezone string. As best as I can tell, at the time of writing (July 2017) all current browsers except for IE11 will return the user timezone as a string.
Most upvoted answer is probably the best way to get the timezone, however, Intl.DateTimeFormat().resolvedOptions().timeZone returns IANA timezone name by definition, which is in English.
If you want the timezone's name in current user's language, you can parse it from Date's string representation like so:
function getTimezoneName() {
const today = new Date();
const short = today.toLocaleDateString(undefined);
const full = today.toLocaleDateString(undefined, { timeZoneName: 'long' });
// Trying to remove date from the string in a locale-agnostic way
const shortIndex = full.indexOf(short);
if (shortIndex >= 0) {
const trimmed = full.substring(0, shortIndex) + full.substring(shortIndex + short.length);
// by this time `trimmed` should be the timezone's name with some punctuation -
// trim it from both sides
return trimmed.replace(/^[\s,.\-:;]+|[\s,.\-:;]+$/g, '');
} else {
// in some magic case when short representation of date is not present in the long one, just return the long one as a fallback, since it should contain the timezone's name
return full;
}
}
console.log(getTimezoneName());
Tested in Chrome and Firefox.
Ofcourse, this will not work as intended in some of the environments. For example, node.js returns a GMT offset (e.g. GMT+07:00) instead of a name. But I think it's still readable as a fallback.
P.S. Won't work in IE11, just as the Intl... solution.
A short possibility for a result in current user's language:
console.log(new Date().toLocaleDateString(undefined, {day:'2-digit',timeZoneName: 'long' }).substring(4));
If you're already using Moment.js you can guess the timezone name:
moment.tz.guess(); // eg. "America/New York"
You can use this script.
http://pellepim.bitbucket.org/jstz/
Fork or clone repository here.
https://bitbucket.org/pellepim/jstimezonedetect
Once you include the script, you can get the list of timezones in - jstz.olson.timezones variable.
And following code is used to determine client browser's timezone.
var tz = jstz.determine();
tz.name();
Enjoy jstz!
You can simply write your own code by using the mapping table here:
http://www.timeanddate.com/time/zones/
or, use moment-timezone library:
http://momentjs.com/timezone/docs/
See zone.name; // America/Los_Angeles
or, this library:
https://github.com/Canop/tzdetect.js
console.log(new Date().toLocaleDateString(undefined, {day:'2-digit',timeZoneName: 'long' }).substring(4).match(/\b(\w)/g).join(''))
To detect something like "America/New York.", you can use the new LocalZone() from the Luxon library.
import { LocalZone } from 'luxon';
const zoneName = new LocalZone().name;
This gets the timezone code (e.g., GMT) in older javascript (I'm using google app script with old engine):
function getTimezoneName() {
return new Date().toString().get(/\((.+)\)/);
}
I'm just putting this here in case someone needs it.
In javascript , the Date.getTimezoneOffset() method returns the time-zone offset from UTC, in minutes, for the current locale.
var x = new Date();
var currentTimeZoneOffsetInHours = x.getTimezoneOffset() / 60;
Moment'timezone will be a useful tool.
http://momentjs.com/timezone/
Convert Dates Between Timezones
var newYork = moment.tz("2014-06-01 12:00", "America/New_York");
var losAngeles = newYork.clone().tz("America/Los_Angeles");
var london = newYork.clone().tz("Europe/London");
newYork.format(); // 2014-06-01T12:00:00-04:00
losAngeles.format(); // 2014-06-01T09:00:00-07:00
london.format(); // 2014-06-01T17:00:00+01:00

Working with different timezones in Javascript

I am working on a cloud based application which deals extensively with date and time values, for users across the world.
Consider a scenario, in JavaScript, where my machine is in India (GMT+05:30), and I have to display a clock running in California's timezone (GMT-08:00).
In this case I have to get a new date object,
let india_date = new Date()
add it's time zone offset value,
let uts_ms = india_date.getTime() + india_date.getTimezoneOffset()
add california's timezone offset value,
let california_ms = utc_ms + getCaliforniaTimezoneOffsetMS()
and finally the date object.
let california_date: Date = new Date(california_ms)
Is there any way to directly deal with these kinds of time zones without having to convert the values again and again?
First, let's talk about the code in your question.
let india_date = new Date()
You have named this variable india_date, but the Date object will only reflect India if the code is run on a computer set to India's time zone. If it is run on a computer with a different time zone, it will reflect that time zone instead. Keep in mind that internally, the Date object only tracks a UTC based timestamp. The local time zone is applied when functions and properties that need local time are called - not when the Date object is created.
add it's timezone offset value
let uts_ms = india_date.getTime() + india_date.getTimezoneOffset()
This approach is incorrect. getTime() already returns a UTC based timestamp. You don't need to add your local offset. (also, the abbreviation is UTC, not UTS.)
Now add california's timezone offset value
let california_ms = utc_ms + getCaliforniaTimezoneOffsetMS()
Again, adding an offset is incorrect. Also, unlike India, California observes daylight saving time, so part of the year the offset will be 480 (UTC-8), and part of the year the offset will be 420 (UTC-7). Any function such as your getCaliforniatimezoneOffsetMS would need to have the timestamp passed in as a parameter to be effective.
and finally the date object
let california_date: Date = new Date(california_ms)
When the Date constructor is passed a numeric timestamp, it must be in terms of UTC. Passing it this california_ms timestamp is actually just picking a different point in time. You can't change the Date object's behavior to get it to use a different time zone just by adding or subtracting an offset. It will still use the local time zone of where it runs, for any function that requires a local time, such as .toString() and others.
There is only one scenario where this sort of adjustment makes sense, which is a technique known as "epoch shifting". The timestamp is adjusted to shift the base epoch away from the normal 1970-01-01T00:00:00Z, thus allowing one to take advantage of the Date object's UTC functions (such as getUTCHours and others). The catch is: once shifted, you can't ever use any of the local time functions on that Date object, or pass it to anything else that expects the Date object to be a normal one. Epoch shifting done right is what powers libraries like Moment.js. Here is another example of epoch shifting done correctly.
But in your example, you are shifting (twice in error) and then using the Date object as if it were normal and not shifted. This can only lead to errors, evident by the time zone shown in toString output, and will arise mathematically near any DST transitions of the local time zone and the intended target time zone. In general, you don't want to take this approach.
Instead, read my answer on How to initialize a JavaScript Date to a particular time zone. Your options are listed there. Thanks.
JavaScript Date objects store date and time in UTC but the toString() method is automatically called when the date is represented as a text value which displays the date and time in the browser's local time zone. So, when you want to convert a datetime to a time zone other than your local time, you are really converting from UTC to that time zone (not from your local time zone to another time zone).
If your use case is limited to specific browsers and you are flexible on formatting (since browsers may differ in how they display date string formats), then you may be able to use toLocaleString(), but browsers like Edge, Android webview, etc do not fully support the locales and options parameters.
Following example sets both the locale and timezone to output the date in a local format that may vary from browser to browser.
const dt = new Date();
const kolkata = dt.toLocaleString('en-IN', { timeZone: 'Asia/Kolkata' });
const la = dt.toLocaleString('en-US', { timeZone: 'America/Los_Angeles' });
console.log('Kolkata:', kolkata);
// example output: Kolkata: 19/3/2019, 7:36:26 pm
console.log('Los Angeles:', la);
// example output: Los Angeles: 3/19/2019, 7:06:26 AM
You could also use Moment.js and Moment Timezone to convert date and time to a time zone other than your local time zone. For example:
const dt = moment();
const kolkata = dt.tz('Asia/Kolkata').format();
const la = dt.tz('America/Los_Angeles').format();
console.log(kolkata);
// example output: 2019-03-19T19:37:11+05:30
console.log(la);
// example output: 2019-03-19T07:07:11-07:00
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data.min.js"></script>
Well, you really do kind of have to convert anytime you want to change the display, but it's not as bad as you think.
First, store all time as UTC. Probably using the milliseconds format, e.g. Date.UTC().
Second, do all manipulation / comparison using that stored info.
Third, if your cloud-based application has an API that API should only talk in terms of UTC as well, though you could provide the ISO string if you prefer that to the MS, or if you expect clients to handle that better.
Fourth and finally, only in the UI should you do the final conversion to the local date/time string, either with the method you're describing or using a library such as momentjs
new Date creates a Date object with a time value that is UTC. If you can guarantee support for the timeZone option of toLocaleString (e.g. corporate environment with a controlled SOE), you can use it to construct a timestamp in any time zone and any format, but it can be a bit tedious. Support on the general web may be lacking. A library would be preferred in that case if you need it to work reliably.
E.g. to get values for California, you can use toLocaleString and "America/Los_Angeles" for the timeZone option:
var d = new Date();
// Use the default implementation format
console.log(d.toLocaleString(undefined, {timeZone:'America/Los_Angeles'}));
// Customised format
var weekday = d.toLocaleString(undefined, {weekday:'long', timeZone:'America/Los_Angeles'});
var day = d.toLocaleString(undefined, {day:'numeric', timeZone:'America/Los_Angeles'});
var month = d.toLocaleString(undefined, {month:'long', timeZone:'America/Los_Angeles'});
var year = d.toLocaleString(undefined, {year:'numeric', timeZone:'America/Los_Angeles'});
var hour = d.toLocaleString(undefined, {hour:'numeric',hour12: false, timeZone:'America/Los_Angeles'});
var minute = d.toLocaleString(undefined, {minute:'2-digit', timeZone:'America/Los_Angeles'});
var ap = hour > 11? 'pm' : 'am';
hour = ('0' + (hour % 12 || 12)).slice(-2);
console.log(`The time in Los Angeles is ${hour}:${minute} ${ap} on ${weekday}, ${day} ${month}, ${year}`);
Getting the timezone name is a little more difficult, it's difficult to get it without other information.

How to detect day light saving and convert to BST (local time) in moment js

I am working on a project and suddenly found an issue. Issue was, server is sending Unix timestamps which is GMT but due to daylight saving the date
was populated as GMT. It can be achievable from server end but there is very simple way where we can convert it to local-time zone(in my case GMT to BST)
Create three variables
getPerfectLocalTime
yourUnixTimestamp
yourFormat
And below is the logic, you can use
var GMTtime = moment(yourUnixTimestamp*1000).format('YYYY-MM-DD HH:mm:ss'); // It should be YYYY-MM-DD format
var convertToUtc = moment.utc(GMTtime).format('YYYY-MM-DD HH:mm:ss');
var localTimeToDate = moment.utc(convertToUtc).toDate();
var isDSTDateTime = moment(GMTtime, 'YYYY-MM-DD');
var month = isDSTTime.format('M');
var day = isDSTTime.format('D');
var year = isDSTTime.format('YYYY');
if(moment([year, month, day]).isDST()){
getPerfectLocalTime = moment(localTimeToDate).format(yourFormat);
}else {
getPerfectLocalTime = moment(yourUnixTimestamp*1000).format(yourFormat);
}
Hope it helps anyone in programming world :)
Given that the only input in your example is yourUnixTimestamp, and you are multiplying by 1000, I'll assume that this is a traditional Unix Timestamp - an integer number in terms of whole seconds since midnight 1970-01-01 UTC.
Simply call moment.unix to parse this particular kind of input value. The resulting moment object will already be in local mode, so you can just format it directly.
moment.unix(yourUnixTimestamp).format(yourFormat)
If you want to know whether or not DST is in effect in the local time zone, you can just ask for that directly too.
moment.unix(yourUnixTimestamp).isDST()
But note that you do not need to know this to format the time correctly. Moment already takes this into consideration internally.

parsing a UTC ISO date to a local time date in javascript/jquery

I have tried to search for the answer already, and although I find answers that are very similar, I don't think they are exactly what I am looking for. Please forgive me if this is already answered elsewhere.
I am trying to parse an ISO date in javascript so that I can compare it to the client system date and display information depending on if the ISO date is before or after the client system date.
This was fine until I needed to support IE8 and now I am stuck.
I have created a function because I have three different dates that I need to do this to.
for example, my ISO date is: 2015-12-22T11:59 in UTC time.
but once my date is parsed, the full date is 11:59 in local time, no matter which time zone i test, it's always 11.59 in THAT time zone.
I know that the function I have created currently doesn't do anything with timezone, this is where I am stuck. I don't know what to add to get my end date to change as a reflection of the timezone of the clients machine.
any help or advice would be greatly appreciated.
I am not able to use something like moments.js because I have an upload restriction.
Jquery is available though. or plain javascript.
<script>
function setSaleContent() {
//creating a new date object that takes the clients current system time. so we can compare it to the dates stored in our array
var currentDate = new Date();
console.log(currentDate + " this is the clients date ");
//These variables actually come from an external array object, but I'm putting them in here like this for this example.
var destinations = {
freedate: "2015-12-16T11:59",
courierdate: "2015-12-22T11:59",
nextdaydate: "2015-12-23T11:59",
}
//fetch all the ISO dates from the array.
var freeDateISO = destinations["freedate"];
var courierDateISO = destinations["courierdate"];
var nextdayDateISO = destinations["nextdaydate"];
//I am creating this reusable function to split up my ISO date for the sake of IE8.. and create it into a date format that can be compared against another date. I know that this isn't doing anything with my timezone and that is where my problem lies.
function parseDate(str) {
var parts = /^(\d{4}).(\d{2}).(\d{2}).(\d{2}):(\d{2})/.exec(str);
if (parts) {
return new Date(parts[1], parts[2] - 1, parts[3], parts[4], parts[5]);
}
return new Date();
}
//I would like this date to change to reflect the time zone of the clients system time.
//currently returns the date at 11.59 regardless of timezone.
//If i was in GMT i would want it to say 11.59
//If i was in CT time I would like this to say 05.59
//If i was in Perth I would like this to say 19:59
var freeDate = parseDate(freeDateISO);
console.log(freeDate + " this is the converted date for IE")
}
window.onload = setSaleContent;
The simple solution is to append Z to the ISO date to indicate it is in UTC time, such as 2015-12-22T11:59Z.
When JavaScript parses that date as a string, it will then automatically convert the UTC date to the local time zone.
While this is simple enough with a parsing call in the form new Date(str);, it will not play nice with your parse call with numerical arguments targeting IE8 and other old browsers.
A polyfill for parsing ISO dates with timezone exists: Javascript JSON Date parse in IE7/IE8 returns NaN
This can replace your custom parseDate function after some modification to take an input string.
Alternatively, implement your own custom date manipulater to account for the local timezone using the .getTimezoneOffset() method on the newly created date, which gives the time zone offset in minutes, but you will have to come up with a method of utilising the offset such as adjusting hours and minutes, due to the limited methods of the JavaScript date object.

how to get current date in the below format using jquery

how to display the date in this below format using jQuery.
Thursday, January 08, 2013
I saw some plugins but wondering if there is a way without using any plugin.
Please advise if there is a straightforward answer using JavaScript, that's fine too.
The simplest answer is to use:
date.toLocaleDateString()
But, it will use the locale defined by the user's system. The American/English locale fitting your desired output. (I'm not sure about other locales and how they format dates).
So, if you want the date string to always be in that format, this will not be the best answer for you. But, if you want the date to match the user's locale, this answer is the simplest and most correct. :)
http://jsfiddle.net/SyjpS/
var date = new Date();
console.log(date.toLocaleDateString()); // Tuesday, January 08, 2013 (on my machine)
EDIT — If you're asking how to change the calendar so that today is Thursday instead of Tuesday, you may need to talk to Caesar about adjusting the calendar realignment. For this, you'll need a time machine. I suggest that you seek out the Doctor, but he may not be willing to change history willy nilly.
Here's a quick/simple example of what you're asking for:
EDIT - I've update the code for reuse and include the day 0 padding change.
var d = new Date();
console.log(formatDate(d));
function formatDate(d){
var months = ["Januaray", "February", "March"]; //you would need to include the rest
var days = ["Sunday", "Monday", "Tuesday"];//you would need to include the rest
return days[d.getDay()] + ", " + months[d.getMonth()] + " " + (d.getDate() < 10 ? "0" + d.getDate() : d.getDate()) + ", " + d.getFullYear();
}
Output for today: Tuesday, Januaray 08, 2013
EXAMPLE
Simply use DateJS not to reinvent the wheel.
You may read the API documentation here:
http://code.google.com/p/datejs/wiki/APIDocumentation
The date methods allow you to retrieve all of the different parts of the date and time as numerical values. In the case of the month of the year and the day of the week, the number that is provided is one less than you would normally expect. The reason for this is that the most common use for these values is to use it to look up the name of the month or day from an array and as arrays in JavaScript are numbered from zero, providing the numbers like that reduces the amount of code needed to do the name lookups.
We can go one better than just doing this lookup using the retrieved values though. What we can do is to add extra methods to the Date object to allow us to retrieve the month and day names whenever we want the exact same way that we retrieve any of the other information about the date.
The probable reason why the following methods are not built into the JavaScript language itself is that they are language dependent and need to have different values substituted into the code depending on the language that you want to display the month and day in. For the purpose of showing you how to code this I am going to use the Emglish names for the months and days. If you want to display dates in a different language you will need to substitute the names from that language for their English equivalents.
What we are going to do is to add getMonthName() and getDayName() methods to all our dates so that we can get the month name or day name by calling these new methods directly instead of having to call getMonth() or getDay() and then do an array lookup of the corresponding name. What we are actually doing is building the required array lookups into the new methods so that we can automatically get the correct names for any of our date objects simply by calling the appropriate method.
We don't neeed all that much code to do this. All you need to do to add the getMonthName() and getDayName() methods to all of the date objects that you use is to add the following short piece of code to the very top of the javaScript code attached to the head of your page. Any subsequent processing of date objects will then be able to use these methods.
Date.prototype.getMonthName = function() {
var m = ['January','February','March','April','May','June','July',
'August','September','October','November','December'];
return m[this.getMonth()];
}
Date.prototype.getDayName = function() {
var d = ['Sunday','Monday','Tuesday','Wednesday',
'Thursday','Friday','Saturday'];
return d[this.getDay()];
}
So now with that in place we can display today's date on the page using those new methods in addition to the existing ones. For example we might use the following to get the full date and display it using an alert:
var today = new Date;
alert((today.getDayName() + ', ' + today.getDate() + ' ' + today.getMonthName() + ', ' + today.getFullYear());
Alternatively, we can just retrieve the current month June and day of the week Sunday and use them however we want just the same as for any of the other parts of the date.
function disp() {
var today = new Date;
document.getElementById('mth').innerHTML = today.getMonthName();
document.getElementById('dow').innerHTML = today.getDayName();
}

Categories