Time arithmetic with moment - javascript

In This Meteor server side code for the users collections, the property createdAt shows something like this ISODate("2017-02-09T01:22:30.894Z").
And in another collection myCol I have the createdAt property with the unix timestamp in milliseconds.
Moment.js is installed.
How can I check the following condition:
myCol.createdAt is after n months from the end of the month when the user was created. thx

Here is one approach that should work (there are of course a handful of other ways to do this...this was the first one that came to mind).
You can convert the Users createdAt property to a moment object like this (assuming your user doc is stored in a var called userOne).
var moment1 = moment(userOne.createdAt);
Then, you can convert the unix timestamp in the other collection like this (assuming the doc is stored in a var called doc).
var moment2 = moment(doc.createdAt);
Now find the end of the moment for moment1 and add in 'N' months.
moment1.endOf('month').add(N, 'months');
Finally, do your comparison.
moment2.isAfter(moment1);

I'm not sure how to get that string representation of the ISODate object, perhaps just .toString().
However, this is how you can get the time difference in months with the myCol.createdAt represented by the current date Date.now().
var isoString = "2017-02-09T01:22:30.894Z"
var today = Date.now()
console.log(moment(isoString).diff(today, 'months'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.0/moment.min.js"></script>

Related

javascript "date.getFullYear()" is returning 3991 [duplicate]

I have tried to get date and time from firebase timestamp as follows:
Date date=new Date(timestamp*1000);
SimpleDateFormat sfd = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
sfd.format(date);
but I'm getting results like:
:02-02-48450 04:21:54
:06-02-48450 10:09:45
:07-02-48450 00:48:35
as you can see the year is not as we live.
So, please help me to fix this.
Your timestamp 1466769937914 equals to 2016-06-24 12:05:37 UTC. The problem is that you are multiplying the timestamp by 1000. But your timestamp already holds a value in milliseconds not in seconds (this false assumption is most likely the reason you have the multiplication). In result you get 1466769937914000 which converted equals to 48450-02-01 21:51:54 UTC. So technically speaking all works fine and results you are getting are correct. All you need to fix is your input data and the solution is quite simple - just remove the multiplication:
SimpleDateFormat sfd = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
sfd.format(new Date(timestamp));
If you are looking to get a Date instance from Timestamp
If you need to get just the Date object from Timestamp, the Timestamp instance comes with a toDate() method that returns a Date instance.
For clarity:
Date javaDate = firebaseTimestampObject.toDate()
According to Firebase documentation, the types that are available JSON are:
String
Long
Double
Boolean
Map<String, Object>
List<Object>
Quoting another Stack Overflow post, I suggest you use JSON date string format yyyy-MM-dd'T'HH:mm:ss.SSSZ instead of epoch timestamp.
Comparing 1335205543511 to 2012-04-23T18:25:43.511Z, you can noticed that:
It's human readable but also succinct
It sorts correctly
It includes fractional seconds, which can help re-establish chronology
It conforms to ISO 8601
ISO 8601 has been well-established internationally for more than a decade and is endorsed by W3C, RFC3339, and XKCD
The .toDate() method should be all you need
You might like the docs here
As an added bonus, you might want very highly human readable output
Date only options
.toDate().toDateString()
.toDate().toLocaleDateString()
Time only options
.toDate().toTimeString()
.toDate().toLocaleTimeString()
Objects
However, if you are receiving an object you might do something like this
{JSON.stringify(createdAt.toDate()).replace(/['"]+/g, '')}
Converting the object into a string then replacing the quotes around the string.
firebase time is basically combination of seconds and nano seconds
time={
seconds:1612974698,
nanoseconds:786000000
}
total_miliseconds=(time.seconds+(time.nanoseconds)*0.00000001)*1000. // 1 nanosecond=1e-9 means 0.00000001
new Date(total_miliseconds)
String time=dataSnapshot.child("timeStamp").getValue().toString();
Long t=Long.parseLong(time);
Date myDate = new Date(t*1000);
Result
Fri May 11 05:37:58 GMT+06:30
For date, you can use this code :
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(time);
String date = DateFormat.format("dd-MM-yyyy", calendar).toString();
For time :
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(time);
String date = DateFormat.format("hh:mm", calendar).toString();
I think its bit late but easiest way is just:
(new Date(timestamp.toDate())).toDateString()
Within the Date() where you put your timestamp add
.toDate()
to the timestamp variable as #jasonleonhard said. Maybe just an example
new Date(timestamp.toDate())

How to get time range of todays date with timezone in javascript and use it in mongo query

I want to run a query in mongo which will get data till 7:00 am, then 7 am to 11 am and then 12 pm to 4 pm of particular that day only. Now these time are stored in different timezone. So I want to know how get data from mongo.
I tried using momentJs to get the the time range but not able to get correct timezone.
var dayStart = moment().zone(timezone).startOf('day');
var now = moment().zone(timezone);
var duration = moment.duration(now - dayEnd);
and my mongo query is
db.CollectionName.find({"created_at": {
'$gte': dayStart,
'$lt': now
}});
I want the three result seperately that is till 7am, 7am-11am & 12pm-4pm. Any help please.
I would still advise against using moment().zone() - at the very least use moment().utcOffset() as it more clearly communicates the approach of the function. However, since you are using .zone() now I will share an example to get you started.
We assume the following:
when a record is saved to your database, the created_at value defaults to UTC
you are the only user of concern
you are located in the Kolkata timezone and when you say 7am, you expect it to be relative to that location on earth
Using the zone feature, you would then need to a value of -330 to translate from UTC to Kolkata. (Since Kolkata is UTC+5:30, we must convert to minutes and then subtract that value 5 * 60 + 30 = 330.)
Given all of that, your values will be as follows:
var dayStart = moment().utc().zone(-330).startOf('day');
var now = moment().utc().zone(-330);
var duration = moment.duration(now.diff(dayStart)).as('minutes');
you had a few typos in your example: dayEnd was an undefined variable, I assumed you meant to use dayStart. also, duration needs to use diff and an argument to format the output, I have used minutes for this example.
You can test further and play around with this example:
https://jsfiddle.net/dusthaines/48wubezy/5/

Parse JSON DateTime object to local time in JQuery by ignoring timezone

I am facing an issue while parsing JSON Date Time object using moment(of course I tried many approaches suggested in Stackoverflow but nothing worked in my case).
In my application, I'm storing a DateTime value as UTC DateTime. Now when I'm displaying I need to display it according to the browser timezone. After going through many StackOverflow questions, I used "moment.js" as below
//From server, the Date object looks like /Date(1506510057813)/
//The equivalent DateTime value stored in Database is 2017-09-27 13:00:57.813
fuction DateTimeFormatter(value)
{
if (value != undefined) {
var newValue = new Date(moment.utc(value));
//But at this line, even with just moment(value) all I am getting is DateTime which is not same as UTC time.
//I don't want any time zone to get appended all I want is just 13:00:57
var newHours = newValue.getHours() - newValue.getTimezoneOffset() / 60;
var newMinutes = (newHours + '.0').split('.')[1] * 6;
newValue.setHours(newHours);
newValue.setMinutes(newMinutes);
return moment(newValue).format(applicationTableDateFormat);
}
else
return "";
}
Please let me know what I am doing wrong or is there any other way I can display time as per browser time zone.
Once you have a UTC moment, you can convert it to local.
moment.utc(value).local().format(...)
https://momentjs.com/docs/#/manipulating/local/
But it sounds like maybe your real problem is when you store the date. If you're storing it as UTC, make sure you actually convert the local value to UTC before you store it. That way when you read it, you get a predictable value that you can safely convert to any locale.
Angularjs has its own mechanism to display formatted dates on views you just needs an absolute representation of a date and it takes care of the rest. And by absolute, I mean, a Date which is settled in a timezone whether it's utc or not, you need to know what timezone you are talking about.
The date filter
It's a filter from the core module of angularjs and it accepts:
"... either as Date object, milliseconds (string or number) or various ISO 8601 datetime string formats (e.g. yyyy-MM-ddTHH:mm:ss.sssZ and its shorter versions like yyyy-MM-ddTHH:mmZ, yyyy-MM-dd or yyyyMMddTHHmmssZ). If no timezone is specified in the string input, the time is considered to be in the local timezone." (Angularjs date filter)
The problem
Angularjs need a proper date input in order to display it correctly, in your case you seem to have the milliseconds format (sort of, /Date(1506510057813)/), you could use that and extract the numeric part and input that on the pipe, or you can change the server to send the ISO 8601 date (a.k.a., yyyy-MM-ddTHH:mm:ss.sssZ).
For example:
let rawDate = '/Date(1506510057813)/';
let re = /\/Date\((\d+)\)\//g; // regex to extract number from the string date
let myDate = new Date(Number(re.exec()[1])) // extract the milliseconds
Or
let rawDate = '2017-09-27T11:00:57.813Z';
let myDate = new Date(rawDate)// and you don't need to do anything else
Either way you'd end up with something like this:
<span> {{ myDate | date }}</span>

Moment.js comparing to times range with am pm

I have an dates array which has an array of appointment times in each date. I loop through a given date to get the appointment times like this :
var newdate = moment(appdate).format('DD/MM/YYYY'); //eg newdate is 04/04/2016
var newtime = moment(apptime).format('h:mm a');
appointmentArr[newdate].forEach(function(value, key) {
console.log(value); //these are all the appointment times for 04/04/2016 eg 11:22:00 AM
});
My question is, how can i check with moment.js, if "newtime" and "value" are within XX mins of each other? ive looked in the docs and on other posts but cant get it right with the AM PM formatting i am using.
To compare two dates with MomentJS you can use moment.diff, and you can specify the unit of measure you want your result in:
newDate.diff(oldDate, 'minutes');
You can then compare that value with your threshold and profit!
EDIT: But you should not format the date before comparing it, since format returns a string. Keep your moment object intact, and format it whenever you need to display it (or save the formatted string in another variable).

How can I convert my normal timestamp into a BSON timestamp?

I am using https://www.npmjs.com/package/mongodb
mongodb has turned my timestamp into BSON (I know this is normal)
my timestamp is this 641912491 where as in the database it looks like this 1457904327000.000000.
I have a document with a key named date_in_the_past which holds my timestamp in it's BSON form.
Note: I am fully aware that the mongodb _id key holds a date but it is of no use to me in this scenario as, that would be the date when the document was written to the db (not the date in the past that I am looking for)
How can I convert my normal timestamp into a BSON timestamp?
I have tried to understand mongodb/js-bson and mongodb/js-bson/blob/master/lib/bson/timestamp.js but I can't see how to do it.
example of what I am looking to do:
var past=timestampToBSON(641912491);
db.collection('docs').find({date_in_the_past:past}).limit(1).toArray(function(e,r){});
If it's stored as a bson timestamp object, you could do something like this
var Timestamp = require('mongodb').Timestamp;
var past = Timestamp(641912491,1);
db.collection('docs').find({date_in_the_past:past})
or
db.collection('docs').find({date_in_the_past: Timestamp(641912491,1)})
it has some more info and examples about it here
https://docs.mongodb.org/manual/reference/bson-types/#timestamps

Categories