Moment.js formatted time incorrect - javascript

I'am using moment.js for formatting date, time and duration.
From api I get e.g. this string "1540034040". It should be converted to 13:14
In my React app I have a function which returns return moment(time, 'HH:mm').format('HH:mm');, but then I get another time 15:40? I see there is a package moment timezone. But I don't want to install another package.
Is there somehow a way to fix this with just moment or javascript, without installing another package?

The time string you are passing ("1540034040") is having 10 digit long. the moment package is expecting this kind of string in millisecond format( 13 digit long string ).
For example "1540034040000".
For this given string the time will get converting to some other past date with different time because you have passed second instead of milliseconds.
For debugging you should try to print whole date and time of the given string ("1540034040") instead of just hours and minutes. it will make things more clear.
You should try passing the milliseconds. i am sure it will fix the issue.

I got this working by:
first transform my string to a number so I am able to use unix() and then format with moment().format()
const timeString = time;
const timeNumber = parseInt(timeString, 10);
return moment.unix(timeNumber).format('HH:mm');

Related

Convert timestamp to "YY/MM/DD" with JS

I need to convert my "80814.89999999851" timestamp to a YY/MM/DD string.
I started by doing this:
var prova = info.originalEvent.timeStamp; //this path lead to: 80814.89999999851
var prova2 = new Date(prova);
Now I have it as a datetime (if i'm not mistaken) but i don't know how to keep just the year/month/day and then convert it to a string.
Can someone help me?
This timestamp is not seconds since unix epoch, its seconds since timeOrigin (most likely time since page was loaded), to convert it to date you need to obtain timeOrigin first. Take a look at this question: Knowing the time origin of event's timestamp.
https://developer.mozilla.org/en-US/docs/Web/API/Event/timeStamp

Get current timestamp in NodeJS in DD-MM-YY-23:59:42 format

I am running NodeJS 8 in AWS Lambda and want to timestamp and attach to an S3 the current day, month, year and current time when the function runs.
So if my function was running now, it would output 220619-183923 (Todays date and 6.39pm and 23 seconds in the evening.)
For something a little complex like this do I need something like MomentJS or can this be done in pure Javascript?
Eventually this will make up a S3 URL such as
https://s3.eu-west-2.amazonaws.com/mybucket.co.uk/BN-220619-183923.pdf
UPDATE
The webhook appears to have some date/time data albeit in slightly different formats that weren't outputted in the Lambda function, so these could prove useful here. Can ':' be used in a URL and could the UTC which I assume is in milliseconds be converted into my desired format?
createdDatetime=2019-06-22T18%3A20%3A42%2B00%3A00&
date=1561231242&
date_utc=1561227642&
Strangely, the date_utc value which is actually live real data. Seems to come out as 1970 here?! https://currentmillis.com/
You don't need moment. I have included a solution that is quite verbose, but is understandable. This could be shorted if needed.
Since you are using S3, you might also consider using the UTC versions of each date function (ie. .getMonth() becomes .getUTCMonth())
Adjust as needed:
createdDatetime= new Date(decodeURIComponent('2019-06-22T18%3A20%3A42%2B00%3A00'))
date=new Date(1561231242 * 1000);
date_utc=new Date(1561227642 * 1000);
console.log(createdDatetime, date, date_utc)
const theDate = createdDatetime;
const day = theDate.getUTCDate();
const month = theDate.getUTCMonth()+1;
const twoDigitMonth = month<10? "0" + month: month;
const twoDigitYear = theDate.getUTCFullYear().toString().substr(2)
const hours = theDate.getUTCHours();
const mins = theDate.getUTCMinutes();
const seconds = theDate.getUTCSeconds();
const formattedDate = `${day}${twoDigitMonth}${twoDigitYear}-${hours}${mins}${seconds}`;
console.log(formattedDate);
UPDATE based upon your update: The code here works as long as the input is a JavaScript Date object. The query parameters you provided can all be used to create the Date object.
You can definitely use MomentJS to achieve this. If you want to avoid using a large package, I use this utility function to get a readable format, see if it helps
https://gist.github.com/tstreamDOTh/b8b741853cc549f83e72572886f84479
What is the goal of creating this date string? If you just need it as a human-readable timestamp, running this would be enough:
new Date().toISOString()
That gives you the UTC time on the server. If you need the time to always be in a particular time zone, you can use moment.

How can I format a string with moment js to suppress minutes if the time ends with ":00"?

I need to format two moment objects to display a time range to users, eg:
6:45PM-9:30PM
I know I can get this with
`${time1.format('h:mmA')}-${time2.format('h:mmA')}`
but I want to suppress minutes when either the start or end time is on the hour, eg:
6:45PM-10PM (instead of 6:45PM-10:00PM)
7PM-9:30PM (instead of 7:00PM-9:30PM)
7PM-10PM (instead of 7:00PM-10:00PM)
I can check to see if the minutes are 0 before and change my formatting string based on that, but that seems inelegant I'd like to do this only using .format if possible. Haven't found anything in the formatting docs about this.
.format does not provide that you want inbuilt. Rather you can use string replace function instead.
`${time1.format('h:mmA').replace(":00","")}-${time2.format('h:mmA').replace(":00","")}`

Using Moment.js like PHP's date and strtotime

I'm a typically server side developer feeling a bit like a fish out of water trying to display time values on the front end. How can I get behavior like PHP's date() and strtotime() functions out of moment.js? I just want a unix timestamp to appear in H:i:s format, and vice versa.
So far I've tried the following, from existing example code and the documentation:
moment(timestamp).format(H:i:s);
moment().duration(timestamp).format(H:i:s);
moment.unix(timestamp).format(h:mm:ss);
moment(formatted,'H:i:s');
Not a SINGLE one of which has worked properly. This may get flagged as duplicate since there are plenty of moment.js questions out there, but I don't know whether it's been updates to the library itself or slightly different context, I have not found one existing solution that has worked for me.
Anybody have any suggestions for these two simple tasks?
EDIT:
I've distilled two different problems out of this. One is that functions the moment docs say should work are giving weird values:
moment(1437462000).format('h:mm:ss')
for instance, which should return 7:00:00 utc, returns 10:17:42. This can be fixed in this case by using moment.unix(1437462000).utc().format('h:mm:ss') instead, but this leads into the second problem - the .utc() function seems to get ignored when converting back from a date into a timestamp:
timestamp = moment(formatted,'DD/MM/YYYY H:m:s').utc().unix();
will still return a timezone corrected value (in my case this is incorrect by several hours since the formatted time in question has nothing to do with the client computer) regardless of whether the .utc() function is included or not.
A few things you should realize:
Unix timestamps should always in terms of UTC. They are never adjusted for time zone in numerical form. If they're adjusted for time zone, that's done during the interpretation of the number, not in its representation.
While traditionally a "Unix Timestamp" is in terms of seconds, many environments use milliseconds instead. PHP's date timestamps are based on seconds, while moment and JavaScript's Date object both use milliseconds by default. Using the moment.unix function will let you pass seconds, and is identical to just multiplying the timestamp by 1000.
Moment has two built-in modes, local and UTC. The default mode is local. It doesn't matter what input you provide, if you don't specify UTC, the moment is adjusted to local. To specify UTC, you use the utc function. There are two forms of the function:
moment.utc(input) // parsing form
moment(input).utc() // conversion form
Both forms take some input and result in a moment in UTC mode. The difference is in how the input is interpreted. In either case, if the input value is unambiguous, the result is the same. For strings, that means the input would contain either a Z (from ISO8601), or a UTC-based offset. All other forms are ambiguous. For example, if I pass "2015-11-08 01:23:45", I will get different results depending on whether I interpret that string as local time or as UTC.
For numbers, they are always interpreted as milliseconds in UTC. However, if you use moment(number) without then calling .utc() then the moment is left in local mode, so any output will display as local time.
When you call moment.unix(input), the input is a number of seconds, but the moment is left in local mode. So to display the UTC time, you would use moment.unix(input).utc().
If your pre-recorded timestamps from your other system are in numeric form, but have been adjusted away from UTC, then they are incorrect. You have bad data, and Moment can't help you unless you know specifically how they have deviated and you write code to counteract that.
Moment's formatters are case sensitive. M is months, m is minutes. H is hours on a 24-hour clock, h is hours on a 12-hour clock. Use two consecutive letters when you want to include zero-padding. Example, HH:mm:ss for 13:02:03 vs. h:m:s for 1:2:3.
Moment's X formatter does not care which mode the moment is in. It will always emit seconds in UTC. Likewise, the x formatter returns milliseconds in UTC, as does moment.valueOf().
Also, your last example:
moment.unix(1437462000).utc().format()
Returns "2015-07-21T07:00:00+00:00" - which I believe is the value you expected.
You also get the same original timestamp regardless of which of these you try:
moment.unix(1437462000).utc().format("X") // "1437462000"
moment.unix(1437462000).format("X") // "1437462000"
moment.unix(1437462000).utc().unix() // 1437462000
moment.unix(1437462000).unix() // 1437462000
For anyone who comes in and is still looking for direct PHP equivalents for date() and strtotime(), here are the ones I ended up using. Matching up to php basically means just completely ignoring any kind of local time information by making sure everything is in UTC. That task is a little different between the timestamp->date and date->timestamp cases, though, so you have to be careful.
date()
Converting a timestamp to formatted date without any client timezone correction
var formatted = moment.unix(timestamp).utc().format('h:mm:ss');
strtotime()
Converting a UTC formatted date back to a timestamp without correcting it to local time:
var new_timestamp = moment.utc(formatted_utc,'DD/MM/YYYY H:m:s').format('X')
//where 'DD/MM/YYYY H:m:s' is the formatted date's format, and
//'X' outputs a unix timestamp without milliseconds.
Notes:
Do not use moment() with parenthesis in the calls:
moment().utc(date,format) will return local time values, not your
input.
Moment.js does not like the use of 'i' for minutes in the formatting,
unlike php.

Convert from string with milliseconds to date object Javascript

I got this problem when dealing with date time conversion. I have timestamp data from postgreSQL database with format like this one
"2011-04-04 19:27:39.92034"
In order to display it in highcharts, I have to convert it to date or time object. Without milliseconds, I easily convert it with Date.js
But milliseconds can't be handled with that library. I tried also with Date.parse but always got NaN.
Any solution for this problem? Thank you
JS built in Date class should be able to handle this, and getTime() can return milliseconds since start 1970 (UNIX time). Watch out for time zone issues though; the constructor may interpret the date/time as being local, but getTime()'s milliseconds since 1970 may be in UTC, baking in a conversion that is difficult to remove.
new Date("2011-04-04 19:27:39.92034").getTime()
1301941659920
Many ways to Rome. The given code will return '(datestr=) 2011-4-4 19:27:39.92'. Is that what you look for?
var darr = '2011-04-04 19:27:39.92034'.split('.')
, dat=new Date(darr[0])
, datestr = '';
dat.setMilliseconds(Math.round(darr[1]/1000));
datestr = [ [dat.getFullYear(),dat.getMonth()+1,dat.getDate()].join('-')
,' ',
[dat.getHours(),dat.getMinutes(),dat.getSeconds()].join(':')
,'.',
dat.getMilliseconds()
].join('');
Can't you just cut of the last 6 chars of that string? You might then round the miliseconds and eventually add a second to you time object.
This is simpler and in one line:
new Date('01/09/2015 06:16:14.123'.split(".")[0])

Categories

Resources