Moment outputting time from now - javascript

I am using moment and moment-timezone to try and output how far away a future time is fromNow (in any timezone).
For example, if the input time was 1 day and h hours away from now, the output would be something like:
Tomorrow at hh:hh AM
Here is how I create my moment-timezone, with some example data:
determineAirTime(dateTime) {
console.log(dateTime); // May 12th 2014 8PM
dateTime =
momentTimezone.tz(dateTime, "MMM Do YYYY hA", momentTimezone.tz.guess());
console.log(dateTime) // 2014-05-12T20:00:00-04:00
}
My problem is converting the above time (2014-05-12T20:00:00-04:00), to a more readable format. Such as tomorrow at 8:00pm, where it takes into account the timezone.
I've tried fromNow() and calendar() in moment, but they only output how many days it will be.
How can I convert my moment-timezone string to an exact date/day/seconds from the currentTime?

You should be careful will "friendly" formats, many users find them annoying. Anyhow, you can use the calendar method:
// Create a date for 13:15:23 tomorrow
var d = new Date();
d.setDate(d.getDate()+1);
d.setHours(13,15,23);
// Show friendly format
console.log(moment(d).calendar());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

Related

How to create Date on server(there utc timezone) and correct display on client?

We escape of using moment now and use date-fns instead. In some places we still use moment on front.
Example of code on server
//date in yyyy/mm/dd format in query params
startOfDay = StartOfDay(new Date(date));
return startOfDay
And when I display this date on front, she changes to local timezone(-4 hours). If i use date-fns-tz and convert to Canada timezone, I will get date with -4 hours and after display -4 hours more. How to resole this issue? I need to add 4 hours to date for my current timeZone. My utcOffset = 4.
Although I am not sure what function your are currently using from date-fns-ts, what has worked for me is to use utcToZonedTime(). This function gets
a date/time in the local time of any time zone from UTC time
import { utcToZonedTime } from 'date-fns-tz'
const now = new Date() // UTC
const nowCustomTimeZone = utcToZonedTime(now, 'Europe/Amsterdam')

moment fromNow returns in 5 hours when parsing utc

trying to format utc time from server in time ago using moment.js fromNow but in some occasions I get "in 5 hours" instead.
timestamp from a server - 2017-11-29T15:03:21
var utcTime = new Date(timestamp);
var timeAgo = moment(utcTime).fromNow();
console.log(timeAgo)
all dates are in past so how can I fix this so I dont get time in a few hours ?
If you want "2017-11-29T15:03:21" treated as UTC, you can either use moment's utc method or just append a "Z" to the string. Since you're already using moment.js, it's more reliable to parse it with moment.js than the built-in parser:
var timestamp = "2017-11-30T00:20:48";
// Append Z
console.log(moment(timestamp + 'Z').fromNow());
// Use .utc
console.log(moment.utc(timestamp).fromNow());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.19.3/moment.min.js"></script>
You need to tell moment that this date is in UTC using moment.utc
var utcTime = new Date(timestamp);
var timeAgo = moment.utc(utcTime).fromNow();
If you don't, moment assumes this date is in your local timezone (which I can tell is Eastern Standard Time by the offset).
In your local timezone, this date is actually 5 hours in the future. Only in UTC is it a few seconds ago, because your local timezone is 5 hours behind UTC.
As per documents https://momentjs.com/docs/#/displaying/fromnow/
you can customize the locale https://momentjs.com/docs/#/customization/relative-time/
As default locale future time will be future: "in %s", having in which is as per documents. if you want to change it then update the locale and use as you want.
Hope this helps

Parsing the hour only

I'm using d3 v3 to parse some intraday data that has the following format:
time,value
09:00,1
09:05,2
09:10,3
...
So I set up a parsing variable like so:
var parseTime = d3.time.format("%H:%M").parse;
And I map the data within the scope of the csv call:
d3.csv("my_data.csv", function(error, rawData) {
var data = rawData.map(function(d) {
return {y_value: +d.value, date: parseTime(d.time)}
});
console.log(data)
}
In the console, I get something strange. Instead of only the hour, I get the full-fledged date, day of the week, month, even time zone.
data->
array[79]
0:Object->
date: Mon Jan 01 1900 09:00:00 GMT+0000
y_value: 1
Do dates need to be this complete? I suppose that could explain why I wound up with monday Jan. 1st, seems like a default of sorts. However, according to d3 time documentation, "%H:%M" is used for hours and minutes. And I could have sworn I did that much correct.
I know something is not quite right because my line graph is throwing the error:
error: <path> attribute d: expected number "MNaN"
My best guess is that the date is over-specified and the axis() is expecting an hour format.
My Question is: Why isn't my data being parsed as hour only? Should I change this from the parsing end? If that's not an option, can I have the x domain read a portion of the date (the hour and minute portion)?
Update: Here is a minimal block for further illustration of my plight.
When you say...
why isn't my data being parsed as hour only?
... it becomes evident that there is a basic misunderstanding here. Let's clarify it.
What is a date?
Simply put, a date is a moment in time. It can be now, or two months ago, or the day my son was born, or next Christmas, or the moment Socrates drank the hemlock. It does'n matter. What is important to understand is that all those dates have a century, a decade, a year, a month, a day, an hour, a minute, a second, a millisecond etc... (of course, those names are conventions that can be changed).
Therefore, it makes little sense having a date with just the hour, or just the hour and the minute.
Parsing and formating
When you parse a string, you create a date object. As we explained above, that date object corresponds to a moment in time, and it will have year, month, hour, timezone etc... If the string itself lacks some information, as year for instance, it will default to some value.
Look at this demo, we will parse a string into a date object, using the correct specifier:
var string = "09:00";
var parser = d3.timeParse("%H:%M");
var date = parser(string);
console.log("The date object is: " + date);
<script src="https://d3js.org/d3.v4.min.js"></script>
As you can see, we have a date object now. By the way, you can see that it defaults to a given year (1900), a given month (January), and so on...
However, in your chart, you don't need to show the entire object, that is, all the information regarding that moment in time. You can show just hour and minute, for instance. We will format that date.
Have a look:
var string = "09:00";
var parser = d3.timeParse("%H:%M");
var format = d3.timeFormat("%H:%M");
var date = parser(string);
console.log("The date object is: " + date);
console.log("The formatted date is: " + format(date));
<script src="https://d3js.org/d3.v4.min.js"></script>
That formatted date is useful for creating axes, tooltips, texts etc..., that is, showing the date you have without showing all its details. You can choose what information you want to show to the user (just the year, or just the month, or maybe day-month-year, whatever).
That's the difference between parsing and formatting.
Why using a formatter?
To finalise, you may ask: why am I using a formatter, if I will end up having the same thing I had at the beginning?
The answer is: you don't have the same thing. Now you have a date, not a string. And, using a date with a time scale, you can accomodate daylight savings, leap years, February with only 28 days, that is, a bunch of things that are impossible to do with a simple string.
PS: The demos above use D3 v4.
EDIT: After your update we can easily see the problem with your code: you have to pass an array to range().
var xScale = d3.time.scale().range([0,width]);
Here is the updated bl.ocks: http://bl.ocks.org/anonymous/a05e15339f7792f175d2bcebccf6bbed/7f23db481f1308eb0d5a1834f7cbc0b17d948167

mongoDB ISO dates to string with moment.js timezone conversion

I am very confused about how mongoDB and javascript handle dates/times.
I have many dates given in a specified timezone. I need to store them in ISO format in mongoDB. For example:
Given: "01.01.2013 15:00", this is in New York City's local time.
As my machine is not set to NYC's timezone, I created a Date object form this with a given offset of -04:00, as NYC is 4 hours behind UTC. So:
var date = new Date("01-01-2013T15:00-04:00"). If I open mongo-express to see what it actually stored, it shows ISODate("2013-01-01T14:00:00.000Z").
Then using moment.js to get it in NYC's time:
var test = moment("2013-01-01T14:00:00.000Z");
var out = test.tz('America/New_York').format('MMMM Do YYYY, h:mm:ss a');
console.log(out); //January 1st 2013, 9:00:00 am
This obviously shows the wrong time, it should show 3:00:00 pm. What am I doing wrong here? I need these times to be the same for any client connecting to my application from any timezone, they shouldn't be converted. What is the best practice here?
If you know that "01.01.2013 15:00" is in "America/New_York" timezone, you can parse it using moment-timezone's moment.tz method.
As moment docs states:
By default, moment parses and displays in local time.
If you want to parse or display a moment in UTC, you can use moment.utc() instead of moment().
Here a live example:
var m = moment.tz("01.01.2013 15:00", "DD.MM.YYYY HH:mm", "America/New_York");
console.log(m.format('MMMM Do YYYY, h:mm:ss a'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.13/moment-timezone-with-data-2012-2022.min.js"></script>

JS: Convert Today's Date to ISOString() with Fixed Time

I'm trying to convert today's date to an ISO standard string but with the fixed time of T00:00:00.000Z.
I can get as far as returning a ISO string of today's date and time:
var isoDate = new Date().toISOString();
// returns "2015-10-27T22:36:19.704Z"
But I wanted to know if it's possible to have a fixed time, so it should return:
"2015-10-27T00:00:00.000Z"
Is this possible?
Any help is appreciated. Thanks in advance!
To get the current UTC date at midnight:
var d = new Date();
d.setUTCHours(0);
d.setUTCMinutes(0);
d.setUTCSeconds(0);
d.setUTCMilliseconds(0);
var output = d.toISOString();
To get the current local date, with the time portion set to UTC midnight:
var d = new Date();
var ts = Date.UTC(d.getFullYear(), d.getMonth(), d.getDate());
var output = new Date(ts).toISOString();
As for which to use, think through your requirements very carefully, The current UTC date and the local date may indeed be two different days.
For example, when it's midnight (00:00) October 27th in UTC, it's 8:00 PM on October 26th in New York.
Also, consider using moment.js, which makes operations like either of these much easier with the startOf('day') and .utc() functions.

Categories