Date weird timezone (GMT+0009) - javascript

I use ExcelJS to parse an Excel into a JavaScript Object.
Here is an excel sample :
As you can see, I must cover multiple format for date and hour. For the date I have no problem. But when it comes to hour, cells with "12:30" and "15:00" value are returned as javascript date object. So I check if its a date or a string and I want to get the string value (10H10 and 18h30 cells are ok because they are considered as string but not the 15:00 and 12:30).
When using VSCode debug tool, I can see that I have this date :
'Sat Dec 30 1899 12:39:21 GMT+0009 (Central European Standard Time)'
'Sat Dec 30 1899 15:09:21 GMT+0009 (Central European Standard Time)'
What I want is a way to cast this result in a string "12:30" or "15:30". I tried many things using moment and Date functions like .toUTCString(), .toGMTString()...

I'm going to assume you have a JS Date object.
Intl.DateTimeFormat would be recommended for formatting date and/or times for users.
But since you want a specific format, it might be easier to format it yourself.
But the time isn't in the correct time zone. You'd first have to convert it to the correct time zone. Except the correct time zone is UTC, and we can access that info about the components of the UTC representation of the date-time without doing any conversion.
[
dt.getUTCHours(),
dt.getUTCMinutes().toString().padStart(2, '0'),
].join(":")

Related

Formatting and parsing a date string without timezone conversion

If I'm in a timezone a few hours before midnight and I try
new Date("2020-03-30T00:00:00.000Z")
it will result in
Sun Mar 29 2020 18:00:00 GMT-0600 (Central Standard Time)
then I realized even
new Date("2020-03-30")
in the wrong timezone will result in the exact same conversion. I have a similar problem with moment.js constructed from similar strings in similar timezones, when I try to call the .format() method it will do a conversion first, sometimes resulting in the wrong day of the month.
How can I format such a date initialized like this and not have to deal with timezone conversions? eg work with just the "raw" date it was initialized from

Match the dates in jQuery with different formats

I have div in which I am providing date and time like this
<div class="timing">
<div id="count-down" data-date="2016-08-31 14:21:00"> </div>
</div>
How would I match or compare with current date, because I am getting current date in this format Wed Aug 31 2016 14:34:58 GMT+0500 (Pakistan Standard Time)
I want to redirect a page to new location if current date is greater than provided date
var currentDate = new Date();
var providedDate = $('#count-down').attr('data-date')
if (currentDate.getDate().toString > providedDate)
{
window.location.href = 'Promo';
$('.timing').css("display", "none");
$('.website-loading').css("display", "block");
}
I have div in which I am providing date and time like this
<div id="count-down" data-date="2016-08-31 14:21:00"> </div>
The string in the data- attribute is not consistent with the format specified in ECMA-262 (the "T" separator between the date and time is missing), so you should manually parse it by either writing a parsing function or use a library and provide the format to parse.
If you use the Date constructor (or Date.parse, they are equivalent for parsing) to parse the string, you may get an invalid date (e.g. in Safari, new Date('2016-01-01 12:00:00') produces an invalid date) since parsing of non–standard strings is entirely implementation dependent.
There are many suitable libraries, some suggestions:
moment.js does parsing, formatting, timezones and arithmetic and has a CDN
fecha.js just does parsing and formatting is very much smaller than moment.js
When you create a Date object, it only has one internal value (called its time value), which is milliseconds since 1970-01-01T00:00:00Z (the javascript epoch, which is the same as the UNIX epoch). When you call the toString method, the result is an implementation dependent string that differs between implementations (in your case you see something like "Wed Aug 31 2016 14:34:58 GMT+0500 (Pakistan Standard Time)", a different implementation may produce something else.
How would I match or compare with current date, because I am getting
current date in this format Wed Aug 31 2016 14:34:58 GMT+0500 (Pakistan Standard Time)
When comparing dates, you really just want to compare the time value. If you compare using the relational operators > or <, they will coerce the dates to their time value so you can compare the dates directly, e.g.:
var providedDate = fecha.parse($('#count-down').attr('data-date'), 'YYYY-MM-DD HH:mm:ss');
if (Date.now() > providedDate) {
// providedDate is in the past
}
Note that since no time zone information is provided in the string to parse, it's treated as a "local" date and time and the host system's current settings are used to determine the offset from UTC, which is then used when calculating the time value. The same system works in reverse when generating a local date and time string from the Date using the default toString method.
Also:
currentDate.getDate()
just returns the date (i.e. the day in the month) as a number without the year and month.

Javascript Parsed Date [duplicate]

This question already has an answer here:
HTML Input type datetime-local setting the wrong time-zone
(1 answer)
Closed 7 years ago.
I'm writing a MVC 5 web application. Into this, I have multiple lists that I propagate and manage through javascript and jquery (one dataset, dependent select controls, and adding ajax callbacks would complicate it unnecessarily.)
The issue I have is: I have a hidden for field formatted to ISO 8601. I run into issues when I display the date in the user's local time, I get a shifted date.
So if the date were stated as: 01-01-2009 (in iso 8601 format: 2009-01-01), the user sees: 12-31-2008.
When I parse the date I'm using:
this.date = new Date(Date.parse(originalString));
/* ^- Date.parse is giving me a number. */
To display the text of the date I am using:
admin.date.toLocaleDateString().Concat(...
Do I need to do any sort of patch-up to adjust things to the proper time-zone? The date, when using console.log(admin.date); shows the original 2009-01-01
I'm thinking there's some parameter I'm not specifying correctly in the toLocaleDateString, but my familiarity level with it is low.
Edit: The goal is to prevent the date shift. All we store is the date, the time aspect is dropped. We have multiple time-zones posting to this database, and the goal is: We use the date of the person who posted it, time dropped. Were the date May 01, 2015, I want anyone who sees that date to see May 01, 2015, the 'toLocaleDateString' is merely a means to get it to appear format correct for their region. So someone who views dates as yyyy-mm-dd will see it properly.
Based on the documentation for Date.parse:
The Date.parse() method parses a string representation of a date, and returns the number of milliseconds since January 1, 1970, 00:00:00 UTC.
You are getting back the epoch time in UTC for your parsed date string hence why the date is off for local times. So, you would need to know the time difference between the local time and UTC which Date.getTimezoneOffset provides (in minutes) in order to set the correct date for the local time:
> var date = new Date(Date.parse('2009-01-01'));
undefined
> date;
Wed Dec 31 2008 19:00:00 GMT-0500 (EST)
> date.getTimezoneOffset();
300
> date.setMinutes(date.getTimezoneOffset());
1230786000000
> date;
Thu Jan 01 2009 00:00:00 GMT-0500 (EST)
One thing to note though is:
...the offset is positive if the local timezone is behind UTC and negative if it is ahead.
So you might need to take care for locales where the value is negative if this applies to your application. If so maybe just omitting negative values would be enough since the date should be the same if a locale's timezone is ahead of midnight UTC.
EDIT: To compensate for possible issues with daylight savings time:
> var dateVals = String.prototype.split.call('2009-01-01', '-');
undefined
> var date = new Date(dateVals[0], dateVals[1] - 1, dateVals[2]);
undefined
> date
Thu Jan 01 2009 00:00:00 GMT-0500 (EST)

How to keep the Date as it is without being converted into local time zone?

I am having issue with the localtime zone things in javascript. If I got a string value from the server is "2014-02-03T00:00:00.000Z", once I pass it into Date object new Date('2014-02-03T00:00:00.000Z'), the new date object will be in localtime zone ex. Sun Feb 02 2014 18:00:00 GMT-0600 (CST). How to keep the value as 'Mon Feb 03 2014 00:00:00' ? I see a lot of people is using moment.js for dealing date, but I don't find any help with this issue.
Thanks
You can use getUTCDate() method. It will return you correct date.
http://jsbin.com/zizukapuba/1/edit?output
It will convert the date into required format with reference to system local timezone.
NOTE: If you use, the getISOString() method, then it will again make the changes with reference to your local time, that is, GMT -6.00.
The Date object stores your date as "2014-02-03T00:00:00.000Z".
When you display your Date object, the toString() function is used to get a string to display the date. toString() displays the date using the local time zone. Try using the toISOString() function or toUTCDateString().

Stop javascript Date function from changing timezone offset

So I have iso date time that need to be converted from a string to date object. How do I keep date from converting it to local browser timezone.
new Date('2013-07-18T17:00:00-05:00')
Thu Jul 18 2013 18:00:00 GMT-0400 (EDT)
I want to get
Thu Jul 18 2013 17:00:00 GMT-0500 (XX)
While MomentJS is a great library, it may not provide a solution for every use case. For example, my server provides dates in UTC, and when the time portion of the date is not saved in the db (because it's irrelevant), the client receives a string that has a default time of all zeros - midnight - and ends with an offset of +0000. The browser then automatically adjusts for my local time zone and pulls the time back by a few hours, resulting in the previous day.
This is true with MomentJs as well.
One solution is to slice off the time portion of the string, and then use MomentJS as described in the other answers.
But what happens if MomentJS is not a viable option, i.e. I already have many places that use a JS Date and don't want to update so many lines of code? The question is how to stop the browser from converting dates based on local time zone in the first place. And the answer is, when the date is in ISO format, you cannot.
However, there is no rule that says the string you pass to JavaScript's Date constructor must be in ISO format. If you simply replace the - that separates the year, month, and day with a /, your browser will not perform any conversion.
In my case, I simply changed the format of the Dates server-side, and the problem was solved without having to update all the client-side JS dates with MomentJS.
Note that the MDN docs for JavaScript's Date class warn about unpredictable browser-behavior when parsing a string to create a Date instance.
You cannot change this behavior of Javascript because it is the only simple way for Javascript to work. What happens is simply that Javascript looks at the time shift, computes the matching timestamp, and then asks the OS for the representation of this timestamp in the local time zone. What is key to understand here is that -05:00 is not an indication of time zone but simply a shift from UTC.
Time zones are complex beasts that are just arbitrary political decisions. The OS provides a service to display time in the local time zone, but not in other time zones. To do that you have to take in account things like DST that are pretty much a hell.
As always with time management, the only decent way to tackle this problem is to use a dedicated library. In Javascript, you'll find Moment.js and Moment.Timezone.js very helpful.
Example http://codepen.io/Xowap/pen/XKpKZb?editors=0010
document.write(moment('2013-07-18T17:00:00-05:00').tz('America/New_York').format('LLL'));
As a bonus, you get a ton of formatting/parsing features from Moment.js.
Please also note that as long as you use the ISO 8601, your date can be pinpointed to a precise moment, and thus be displayed in any timezone of your liking. In other words, JS "converting" your date doesn't matter.
You can use a library such as Moment.js to do this.
See the String + Format parsing.
http://momentjs.com/docs/#/parsing/string-format/
The following should parse your date you provided, but you may need to modify it for your needs.
var dateString = "2013-07-18T17:00:00-05:00";
var dateObject = moment(dateString, "YYYY-MM-DDTHH:mm:ssZ").toDate();
Alternatively, see Moment's String parser, which looks like it is in the format you provided, with the exception of a space between the seconds of the time and the time zone.
http://momentjs.com/docs/#/parsing/string/
This is an old question that recently got linked in an answer to a newer question, but none of the existing answers seem to fully address the original question.
In many cases the easiest way to format and display a datetime string in the time zone that it is received, is not to convert the string to a Date object at all. Instead, just parse the datetime string and recombine the parts into the desired format. For example, if you can live without the day of the week in the output requested in the question, you could do something like the following to handle the requested input and output format (including the day of the week adds enough complexity that it might be worth using a library at that point). Of course, this approach requires modification based on the format of the datetime strings you are receiving on the client side.
const months = {1: 'Jan', 2: 'Feb', 3: 'Mar', 4: 'Apr', 5: 'May', 6: 'Jun', 7: 'Jul', 8: 'Aug', 9: 'Sep', 10: 'Oct', 11: 'Nov', 12: 'Dec'};
const format = (datetime) => {
const [date, time] = datetime.split('T');
const [y, m, d] = date.match(/\d+/g);
const [t, tz] = time.split(/(?=[+-])/);
return `${months[Number(m)]} ${d} ${y} ${t} GMT${tz}`;
};
const dt = format('2013-07-18T17:00:00-05:00');
console.log(dt);
// Jul 18 2013 17:00:00 GMT-05:00
There are JavaScript and other library methods that will allow you to convert your datetime string to a Date instance and then display it in a specific time zone if you are consistently receiving datetime strings from one or a few specific time zones that are easily identified on the client side. Following are a couple of examples.
toLocaleString enables you to display a date in a specific time zone but the options parameters required to set the time zone are not supported across all browsers (as of the date of this answer). For example (note that parsing of date strings with the Date constructor is still discouraged, but most modern browsers will handle an ISO 8601 format string like the one below):
const dt = new Date('2013-07-18T17:00:00-05:00');
const ny = dt.toLocaleString('en-US', { timeZone: 'America/New_York' });
console.log(`Local: ${dt}`);
console.log(`New York: ${ny}`);
You could also use Moment.js with Moment Timezone to display a date in a specific time zone. For example:
const ny = moment('2013-07-18T17:00:00-05:00').tz('America/New_York').format();
console.log(`New York: ${ny}`);
<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>
It is important to note the following when working with datetime strings and time zones in JavaScript. The JavaScript Date constructor DOES NOT change the time zone offset. When you create a date from a string using ISO 8601 format as in the question example, Date does the following:
Creates a JavaScript Date instance that represents a single moment in
time. Date objects use a Unix Time Stamp, an integer value that is the
number of milliseconds since 1 January 1970 UTC.
In other words, JavaScript Date instances do not store (or change) time zone offsets. The reason you often see output from a JavaScript Date in your local time zone is that toString is the default method called when you log a Date instance to the console (or use various other approaches to output your date). In most browser implementations, this method relies on the browser's local time zone to convert the number of milliseconds since 1 January 1970 UTC into a string representation of the date.
Wonder if this would help:
function goAheadMakeMyDate(s){
var d = new Date(s);
// override Date.toString()
d.toString = function(){ return ''+s; };
return d;
}
var example = goAheadMakeMyDate("Fri 19 July 2013 12:00:00 GMT");
example.toString() // returns string actually used to construct the date
'Fri 19 July 2013 12:00:00 GMT'
example.toLocaleString()
'Fri Jul 19 2013 08:00:00 GMT-0400 (EDT)'
1*example // gives seconds since epoch
1374235200000
With your input:
example = goAheadMakeMyDate('2013-07-18T17:00:00-05:00')
{ Thu, 18 Jul 2013 22:00:00 GMT toString: [Function] }
> example.toString()
'2013-07-18T17:00:00-05:00'
> example.toLocaleString() // I live in GMT-4
'Thu Jul 18 2013 18:00:00 GMT-0400 (EDT)'
> 1*example // convert to integer date
1374184800000
However, if you start modifying this date, the toString will not change and will bite you.
I have a scenario where date time stamp needs to update only once. In detail I have button in my application and when clicked on it will generate a PDF along with timestamp footer and when refreshed it should not change date time.
For the above scenario I have used localStorage.setItem('','') and getItems. In precise.... when clicked on generate button I have used localStorage.setItem('','') and in the generating footer logic I have used localStorage.getItem('') dats it....
Explanation for above logic:
Whenever we are generating I am setting current date time and when generating am calling getItem which will pick the set date time from local storage.
This will reset again when clicked on Generate button.
Hope this helps someone in need..... :-)

Categories

Resources