I'm scraping a site, and the dates come in two forms:
11-22-2011 07:41 AM
Today # 07:41 AM
Both of these are GMT-8. I'd like to get a unix timestamp out of these, so that I can construct a meaningful date object
Any idea what timezone this might be? Around a month ago, the site was gibing GMT-9 times. Can javascript handle Daylight Saving Time automatically?
I'm having great difficultly parsing them. Part of the problem is the time zone.
At the moment, I'm using Date.js' parseExact:
date = Date.parseExact(date + ' PDT', 'MM-dd-yyyy H:mm tt zzz');
Hovever, this seems to get parse 12AM as 12:00, not 0:00. Additionally, I'm at a total loss as to how to handle the ones starting with today #.
When I try both of your examples using the interactive parser at http://www.datejs.com/ I get the expected results.
The timezone in question is likely "US West Coast", aka "Pacific Time".
Unfortunately that means different things at different times of the year. In the spring and summer that timezone is called "PDT" (GMT-0700) and the rest of the time it's called "PST" (GMT-0800).
To further complicate matters the dates on which that changes aren't the same as the dates on which other zones (e.g. in Europe) change.
I don't think there's a way of specifying a timezone value to Date.js that can take that into account automatically.
You could write your own, timezone-aware date parsing logic which takes into account the timezone of the remote server.
pseudo-code:
if date starts with "Today #"
replace "Today #" with currentDateInRemoteTimezone in date
endif
parse_timezone-aware(date)
Why not just add HHHH:mm zzz to get 12:00?
Use a lowercase h for the hour to get 1-12. The uppercase H gives 0-23. From your examples I would use a format of
MM-dd-yyyy hh:mm tt
Documentation
You should handle "Today # " separately. When you find that string, expect the next token to be a time in the form hh:mm tt. Parse the second part as a time and combine it with today's (local) date. That is not hard to do programmatically with Date.js functions, but you won't find a single format string that captures the "Today #" part (as you know).
Related
How to convert date like '2021-06-01T11:17:00-07:00' to ISO standard? What is this format?
let date = new Date('2021-06-01T11:17:00-07:00');
console.log(date.getHours() + " :" + date.getMinutes());
I should get 11:17 but I am getting back 23:47
So something going wrong in understanding the correct format of date?
To reverse engineer,
If I convert date my expected date which is "2021-06-01 11:17:00" to IsoString then the value which I get is 2021-06-01T05:47:00.000Z
which is not equal to 2021-06-01T11:17:00-07:00
PS - So from comments I got to know this format is in MST which is 7 hours behind UTC
The input specifies a time zone, so it specifies a time at which in Salt Lake City it is 11:17. That same moment corresponds to 23:47 in New Delhi, which is your time zone.
So when you tell JavaScript to read the input, it will know it is a specification in Mountain Standard Time (-07:00), and will store the date in UTC. When you output the date as you do, JavaScript will use your locale and output it as 23:47, which is the exact same moment that the input specifies.
If you want the time to output as 11:17, then apparently you don't want to consider that it is a local time in Salt Lake City, but ignore that, and just consider it to be 11:17 in your time zone.
In that case, you should change the input, and remove the time zone specification:
let date = new Date('2021-06-01T11:17:00'); // No time zone specified -> is interpreted as local time
console.log(date.getHours() + " :" + date.getMinutes());
If the input string is variable, you can strip the time zone by keeping only the first 19 characters of the input before passing it to the Date constructor.
But be aware that when you strip the time zone, you actually change the time specification in the input to a different one. It is no longer the same time.
Have you tried using the Vanilla javascript Date class? Should be able to pass that into the constructor and then convert it to the desired format. For example:
const date2 = new Date('1995-12-17T03:24:00');
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date
You could also try using the Moment library in Javascript, although many people are trying to move away from this.
I have the following date:
25-JAN-18 01.31.02 AM +00:00
and am trying to convert into a Postgres compatible timestamp with time zone format.
I am trying the following code to convert into the compatible format:
document.getElementById("parsedDate3").innerHTML = moment("25-JAN-18 01.31.02.923526 AM +00:00 ", "d-MMM-YY hh.mm.ss A Z");
But I am getting the output as
Mon Jan 01 2018 02:31:02 GMT+0100
Can anyone please help me with this.
You are using lower-case d which is for the day of the week, 0 (Sunday) through 6 (Saturday).
Use upper-case D instead, which is for the day of the month.
Note that Moment's formatting tokens are slightly different than in other libraries and languages, so check the chart in the docs carefully.
Also:
In your code you have 6 extra digits following the seconds. If you need to account for those, use SSSSSS. Otherwise they are ignored.
You shouldn't assign a Moment object directly to an HTML element's innerHTML property. Instead, call the .format() function on the Moment object first to generate a string. You can optionally pass an argument to this function, to control the output format.
You can simply do it in PostgreSQL:
SELECT to_timestamp('25-JAN-18 01.31.02.923526 AM +00:00', 'DD-MON-YY HH.MI.SS.US AM TZH:TZM');
to_timestamp
-------------------------------
2018-01-25 02:31:02.923526+01
(1 row)
This will work for PostgreSQL v11 or better.
Earlier versions of to_timestamp cannot parse the time zone information yet.
If you need it to work on 9.6, and you know that the time zone is always going to be +00:00, you could simple omit the TZH:TZM in the format string.
I'm using moment library to convert date into a utc format. here is my date string:
var dateString = "2019-01-31T11:33:16.952+0000";
new Date("2019-01-31T11:33:16.952+0000") // o/p: Thu Jan 31 2019 03:33:16 GMT-0800 (Pacific Standard Time)
since this date is less than a week from today's date, I'm trying to display a text saying "n days ago" instead of actual date. But for some reason I'm getting a future date displayed as "6 days ago" when I do this:
moment.utc("2019-01-31T11:33:16.952+0000").local().fromNow() // shouldnt this display "5 days ago"??
Not sure why moment is not converting the date correctly, any ideas what could be wrong here?
I guess(Considering use of local() converts to your local timezone so time is deducted because you might be in -ve TimeZone) this answer is a solution you're expecting:
Ideally, you would want to pass a UTC timestamp from your server to
the client. That doesn't mean you have to switch your whole server
over to UTC, it just means that you would convert from the time in
your database to UTC on the server before sending it over the web.
Sure, it would be even better if you actually stored times in UTC, but
you said you aren't in a position to make that sort of change right
now. But let's just work off the assumption that you can't change
anything at all on the server.
We'll also assume that your server is fixed to the UTC-07:00 offset.
In real life, this would only be true for places like Arizona that
don't follow daylight saving time. So if you are in Los Angeles and
are in Pacific Time, then some of your data is based on UTC-07:00, but
some of it is based on UTC-08:00. That requires a lot more work if you
want to do it in JavaScript.
Let's also assume that the input is already a string in ISO8601
format. (If it's not, then let me know and I will adjust this code.)
var s = "2013-09-11 18:00:00"; // from action.timeStamp
var actionTime = moment(s + "-07:00", "YYYY-MM-DD HH:mm:ssZ");
var timeAgo = actionTime.fromNow(); The reason your other code didn't
work is because in the first line, you are affected by the time zone
of the browser. The zone setter in the second line just changes the
zone for formatting, not changing the actual moment in time.
Also, when you dump a moment to the console for debugging, make sure
you format it for output. Otherwise you are just looking at its
internal property values, which may or may not make sense directly.
I found a couple other posts but they didn't have something specific to what I was looking for.
Here's the scenario:
A user in China (although it could be anywhere in the world) inputs a date time into a field that represents a local time in the U.S. So even though their local machine might be 1:11 AM 02/15/2018 in Beijing, the user is entering a date in Austin, TX for 11:11 AM 02/14/2018 into the date time field.
This is the string I'm pulling from the input field:
'2018-02-14T11:11'
How can I use moment.js to make sure that when I convert '2018-02-14T11:11' to UTC, the UTC string always reflects Austin time, not Beijing time? At the end of the day, we won't know which timezone the user is from, but we will always know the entered timezone will be in Central Standard Time.
What seems to be happening with the below is that when I use these to convert to UTC, the dates are still not reflecting CST, or they are offset incorrectly by several hours.
moment('2018-02-14T11:11').zone("America/Chicago").format()
moment('2018-02-14T11:11').tz("America/Chicago").format()
moment('2018-02-14T11:11', 'CST').tz("America/Chicago").format()
moment('2018-02-14T11:11', "America/Chicago").tz("America/Chicago").format()
To UTC:
moment.utc('2018-02-14T11:11').tz("America/Chicago").toISOString()
I'm definitely missing something. Any advice would be appreciated!
Thanks in advance!
You're close - you will need the Moment-Timezone addon, and then it's like this:
moment.tz('2018-02-14T11:11', "America/Chicago").utc().format()
Let's break that down:
// create the moment with a specific time zone
var m = moment.tz('2018-02-14T11:11', "America/Chicago");
// convert to UTC
m.utc();
// format the output
var s = m.format();
Just add another scenario that I got:
Parse '2018-02-14Z', but ignore 'Z' (UTC), just use local time zone or a specified timezone.
You can simply remove 'Z' from the string or do these:
moment('2018-02-14Z', 'YYYY-MM-DD') will ignore 'Z' or any unmatched characters.
moment.tz('2018-02-14Z', 'YYYY-MM-DD', 'America/Chicago') will use the given timezone.
Of course, you should not do this in the first place. A correct timezone should be used.
I do let fullcalendar initialize normally. So it represents current date. (Midnight->midnight, 1day, 1h slots)
From some other datasource I get data with timestamps. The format is "YYYY-MM-DD HH:mm" (transmitted as a string, no timezone information)
So I convert that string to a moment object and test against fullcalendar.start and .end to see if it is within.
moment("2016-04-07 00:00") == $('#calendar').fullCalendar('getView').end
This results in false though the following command
$('#calendar').fullCalendar('getView').end.format("YYYY-MM-DD HH:mm")
returns
"2016-04-07 00:00"
I also tried to compare with diff
moment("2016-04-07 00:00").diff( $('#calendar').fullCalendar('getView').end,"minutes")
which returns
120
Some research on the calendars.end object in Chrome Dev Tools revealed that it internally is represented as
2016-04-07 02:00 GMT+0200
This looks strange to me. I am in timezone 2h ahead of GMT. So it should correctly say 2016-04-07 00:00 GMT+0200, should it not?
This also explains why the diff test above resulted in 120 minutes.
Can someone help? I do not get where the conversion problem comes from. I am using only dates with no timezone information. And as said above, fullcalendar initalizes with no gotodate information and shows a time bar from 00:00 to 00:00. So why does it come that there is this 2h difference?
Thanks a lot. I do understand things a lot better now.
Some of the dates I tried to compare were 'now'. I got 'now' by
var n = moment()
That turned out to be a date time including my timezone.
E.g. moment().format() resulted in '2016-04-07 00:00 GMT+0200' and I now see how this went wrong excepting a comparison against full calendar.end to be true but it was false as '2016-04-07 00:00 GMT+0200' is '2016-04-06 22:00' at UTC.
As
moment.utc()
does not work, I know ended up with using
moment.utc(moment().format('YYYY-MM-DD HH:mm'))
This now seems to work as this treats my local time as it would be the 'numerical same time' at UTC.. thus matching with how fullcalendar handles times internally (ambiguously-zones moments).
Thanks
A few things:
The timezone parameter controls how FullCalendar works with time zones.
By default, FullCalendar uses "ambiguously-zoned moments". These are customizations to moment.js made within fullCalendar. The docs state:
The moment object has also been extended to represent a date with no specified timezone. Under the hood, these moments are represented in UTC-mode.
Thus, to compare dates in this mode, treat them as if they were in UTC.
moment.utc("2016-04-07 00:00")
To compare moments, use the moment query functions, isSame, isBefore, isAfter, isSameOrBefore, isSameOrAfter, and isBetween.
In this case, since FullCalendar's start is inclusive but the end date is exclusive, you probably want to compare like this:
var cal = $('#calendar').fullCalendar('getView');
var start = cal.start;
var end = cal.end;
var m = moment.utc("2016-04-07 00:00"); // your input
var between = m.isSameOrAfter(start) && m.isBefore(end);
Note that there's an pending enhancement to moment's isBetween functionality for a future release that will give you control of exclusivity, but currently isBetween is fully inclusive, so you have to use the combination of functions shown here.