in a project we are using momentjs with date. And from backend we become the date in the following format: 2016-10-19T08:00:00Z (don't ask me why...)
Now we are setting a new date in frontend from some selectboxes. And I am trying to convert this in the same format:
const date = '25.03.2021';
const hour = '13';
const minute = '45'; // this 3 values come from value of selectboxes
const rawDate = moment(date).hour(hour).minute(minute);
// trying to convert to 2021-03-25T13:45:00Z
rawDate.format(); // output: 2021-03-25T13:45:00+00:00
rawDate.format('DD.MM.YYYY hh:mm:ss'); // output: 03.01.2022 08:00:00
rawDate.format('DD.MM.YYYY hh:mm:ss z'); // output: 03.01.2022 08:00:00 UTC
rawDate.format('DD.MM.YYYY hh:mm:ss Z'); // output: 03.01.2022 08:00:00 +00:00
rawDate.toISOString(); // output: 2022-01-03T08:00:00.000Z
I know I could probably just use format() or toISOString() and slice/replace the last bit. But I like to know is there a way without any string concat/manipulation?
You could use moment.utc() to ensure your date is in UTC, then use .format() with the format string DD-MM-YYYYTHH:mm:ss[Z].
I'd also suggest explicity defining the format you are parsing from in the moment() call, e.g. pass 'DD.MM.YYYY' as the second argument.
The reason the backend takes dates in this format is that it's a standardized way of formatting dates to make them machine-readable and consistent (ISO 8601)
const date = '25.03.2021';
const hour = '13';
const minute = '45';
// Raw date will be in the UTC timezone.
const rawDate = moment(date, 'DD.MM.YYYY').hour(hour).minute(minute).utc();
console.log(rawDate.format('DD-MM-YYYYTHH:mm:ss[Z]'));
<script src="https://momentjs.com/downloads/moment.js"></script>
You can try convert to UTC ..?
i.e. Do you intend to make use of a UTC date/time..?
const date = '2021-03-25';
const hour = '13';
const minute = '45'; // this 3 values come from value of selectboxes
const rawDate = moment(date).hour(hour).minute(minute);
const utc = moment.utc(rawDate);
console.log(rawDate.format('DD.MM.YYYY hh:mm:ss'));
console.log(utc.format()); //2021-03-25T11:45:00Z
I'm obtaining data.value which is a time in the format: hh:mm a - for example 12:30 am.
I also know:
the local timezone of the user (userTimeZone)
the timezone of the venue (venueTimeZone)
I need to convert the time selected by the user (data.value) to the correct date in the venueTimeZone. For example, if the user is in Americas/New York and they selected 1:30PM on the 20/05/2022, and the venue is in Americas/Los Angeles - the value I am interested in obtaining is 20/05/2022 10:30AM.
This is my attempt, however the timezone itself doesn't change - I think this is because when I create the userDateTime with moment I don't specify a time offset, but I'm not sure how to obtain the offset from userTimeZone, whilst accounting for DST.
const userTimeZone = _.get(
Intl.DateTimeFormat().resolvedOptions(),
['timeZone']
);
const venueDateStr = new Date().toLocaleString('en-US', {
timeZone: venueTimeZone,
});
const Date = new Date(restaurantDateStr);
const venueYear = venueDate.getFullYear();
const venueMonth = `0${venueDate.getMonth() + 1}`.slice(-2);
const venueDateOfMonth = `0${venueDate.getDate()}`.slice(-2);
const userDateTime = createDateAsUTC(
moment(
`${venueDateOfMonth}/${venueMonth}/${venueYear} ${data.value}`,
'DD/MM/YYYY hh:mm a'
).toDate()
).toLocaleString('en-US', { timeZone: venueTimeZone });
EDIT - I do not have the city offset, I have the timezone name, therefore I cannot use any suggested answer which relies on city offset.
Consider using Luxon - the successor to Moment. (See Moment's project status.)
// Parse your input string using the user's local time zone
// (this assumes the current local date)
const local = luxon.DateTime.fromFormat('1:30 pm', 'h:mm a');
// Convert to the desired time zone
const converted = local.setZone('America/Los_Angeles');
// Format the output as desired
const formatted = converted.toFormat('dd/MM/yyyy h:mm a').toLowerCase();
console.log(formatted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/luxon/2.4.0/luxon.min.js"></script>
You could also do this without a library, however you may find that not all browsers will parse the input string, and your output format is up to the browser as well.
// Get the current local date as a string
const date = new Date().toLocaleDateString();
// Parse the date and time in the local time zone
// Warning: This is non-standard and may fail in some environments
const dt = new Date(date + ' 1:30 pm');
// Format the output, converting to the desired time zone
const result = dt.toLocaleString(undefined, { timeZone: 'America/Los_Angeles' });
console.log(result);
There are, of course, manual ways to parse and format dates (using regex, etc.) but I'll leave that up to you or another person to complete.
I am trying to save a string in MongoDB as a date but having hard times for storing the right values.
In Mongoose schema data value is stored as Date, however, I pass the value to data as new Date("MM-dd-YYYY") but when I look up in the database the value is transformed to this format ISODate("YYYY-MM-dd-1T21:00:00Z")
The format wouldn't bother me if the date would be the same but as you notice the value in the database is one day earlier then the value which I want to be.
So instead of 2018-09-20 is 2018-08-19. My guess is that default UTC time is not the same or something like that but how can I set the correct UTC time?
Edit:
var mongoose = require('mongoose')
var dateformat =require('moment');
//Schema
var ReservationSchema = mongoose.Schema({
name : {
type:String,
required : true,
},
numberOfGuests : {
type : Number ,
required : true,}
,
email: {
type : String,
required:true,
},
phone: {
type : String,
required:true,
},
data:{
type:Date,
require:true,
},
timetables:{
type:String,
require:true,
},
furtherRequests: {
type : String,
}
});
var reservvar = module.exports = mongoose.model('Rezervari', ReservationSchema ,'Rezervari');
module.exports.createReservation = function (query,callback){
//query.data = dateformat.utc(query.data).format("MM-DD-YYYY")
reservvar.create(query,callback);
}
module.exports.getReservations = function (callback){
reservvar.find({},callback);
}
Index.js file :
app.get('/api/reservations',function(req,res) {
Rezervari.getReservations(function(err,reserv){
if(err){
throw err;
}
var changetime = reserv[1].data;
console.log(reserv[1].data)
changetime = dateformat.utc(changetime).format("MM-DD-YYYY") // this one returns the date in desired format but with wrong values as stored in db
console.log(changetime)
res.json(reserv);
});
});
app.post('/api/createrezervare', function (req,res) {
const reserv = req.body
const name = reserv.name
const numberofg = reserv.number
const phone = reserv.phone
const email = reserv.email
const data = reserv.date
const timetable = reserv.time
const furtreq = reserv.frequests
Rezervari.createReservation({name:name,numberOfGuests:numberofg,phone:phone,email:email,data:data,timetables:timetable,furtRequests:furtreq},function(err,reserv){
if(err){
throw err}
res.json({status:true})
})
})
You are inserting a Javascript Date Object from Node.js, and that same Date is being inserted in MongoDB, it's being inserted correctly.
I think you are confusing how dates are stored internally and how are they formatted when you print them.
When you check the content of your data in MongoDB it's just shown in that particular format, an ISO date. If you take a close look at the date shown you can see a Z a the end, Z means "zero hour offset" also known as "Zulu time" (UTC).
In Javascript when you create a Date object without setting the timezone, it's by default created in your system timezone. Also, Date objects are not stored with any format, nor in JS nor in MongoDB. In JS, dates are stored internally as time values (milliseconds since 1970-01-01).
Supposing we are in Japan, JST time (UTC+9):
const d = new Date("09-20-2018");
console.log(d.getTime()); // 1537369200000
console.log(d.toString()); // Thu Sep 20 2018 00:00:00 GMT+0900 (JST)
console.log(d.toISOString()); // 2018-09-19T15:00:00.000Z
First we are printing out the number of ms, after the Date including the timezone, and finally the ISO Date, almost same format that MongoDB uses to print dates in the Mongo shell (anyway, in UTC).
So, new Date("09-20-2018") is going to store the milliseconds until 09-20-2018 00:00 in Japan Time. Then, if you insert that object in MongoDB, internally it will store the correct date (I don't know internal details of MongoDB, but maybe it's storing the milliseconds as well).
If you check MongoDB you will see something like ISODate("2018-09-19T15:00:00Z").
I am trying to convert the below date to a javascript Date() object. When I get it back from the server, it is a Timestamp object,
Screenshot from Firebase Firestore console:
When I try the following on a list of objects returned from firestore:
list.forEach(a => {
var d = a.record.dateCreated;
console.log(d, new Date(d), Date(d))
})
I get this output:
Clearly the Timestamps are all different, and are not all the same date of Sept 09, 2018 (which happens to be today). I'm also not sure why new Date(Timestamp) results in an invalid date. I'm a bit of a JS newbie, am I doing something wrong with the dates or timestamps?
The constructor for a JavaScript's Date doesn't know anything about Firestore's Timestamp objects — it doesn't know what to do with them.
If you want to convert a Timestamp to a Date, use the toDate() method on the Timestamp.
You can use toDate() function along with toDateString() to display the date part alone.
const date = dateCreated.toDate().toDateString()
//Example: Friday Nov 27 2017
Suppose you want only the time part then use the toLocaleTimeString()
const time = dateCreated.toDate().toLocaleTimeString('en-US')
//Example: 01:10:18 AM, the locale part 'en-US' is optional
You can use Timestamp.fromDate and .toDate for converting back and forth.
// Date to Timestamp
const t = firebase.firestore.Timestamp.fromDate(new Date());
// Timestamp to Date
const d = t.toDate();
How to convert Unix timestamp to JavaScript Date object.
var myDate = a.record.dateCreated;
new Date(myDate._seconds * 1000); // access the '_seconds' attribute within the timestamp object
Please use toDate() method and then convert it into the format using angular pipe like this -
{{ row.orderDate.toDate() | date: 'dd MMM hh:mm' }}
apart from other answers you can do it like this as well
//date from firebase is represented as
let time = {
seconds: 1613748319,
nanoseconds: 47688698687,
}
const fireBaseTime = new Date(
time.seconds * 1000 + time.nanoseconds / 1000000,
);
const date = fireBaseTime.toDateString();
const atTime = fireBaseTime.toLocaleTimeString();
console.log(date, atTime);
At last, I could get what I need. This returns date as 08/04/2020
new Date(firebase.firestore.Timestamp.now().seconds*1000).toLocaleDateString()
const timeStampDate = record.createdAt;
const dateInMillis = timeStampDate._seconds * 1000
var date = new Date(dateInMillis).toDateString() + ' at ' + new Date(dateInMillis).toLocaleTimeString()
OutPut Example: Sat 11 Jul 2020 at 21:21:10
This might help:
new Date(firebaseDate._seconds * 1000).toUTCString()
A simple way is to convert firestore timestamp to epoch timestamp is by using toMillis() method on firestore timestamp.
For example:
You have a firestore timestamp
created_on : Timestamp { _seconds: 1622885490, _nanoseconds: 374000000 }
let epochTimestamp = created_on.toMillis()
//epochTimestamp = 1621081015081
//Now this timestamp can be used as usual javascript timestamp which is easy to manipulate.
let date = new Date(epochTimestamp) //date = Sat May 15 2021 17:46:55 GMT+0530 (India Standard Time)
The timestamp object you get from firestore has a toDate() method you can use.
list.forEach(a => {
var d = a.record.dateCreated;
console.log(d.toDate())
})
Here's a quote from firebase docs about the toDate() method
Convert a Timestamp to a JavaScript Date object. This conversion
causes a loss of precision since Date objects only support millisecond
precision.
Returns Date JavaScript Date object representing the same point in
time as this Timestamp, with millisecond precision.
https://firebase.google.com/docs/reference/js/firebase.firestore.Timestamp#todate
This works for me.
new Date(firebaseDate.toDate())
This works for me
let val = firebase.timestamp // as received from the database, the timestamp always comes in an object similar to this - {_nanoseconds: 488484, _seconds: 1635367}
(new Date( (val.time._seconds + val.time._nanoseconds * 10 ** -9) * 1000)).toString().substring(17, 21)
Lots of answer here, but as a rookie I found most of them confusing.
So for rookies like me, here is a simple explanation of how to convert a Firestore date/Timestamp to a Javascript Date() and why you need to.
Why convert?
Firestore stores Dates as a Timestamp object. This is not the same as a Javascript Date() object.
This was confusing to me because if you send a Date() object to Firestore, and then retrieve it, it will hand you back a Timestamp object. Like if you hand Firestore a dollar, it will hand you back 4 quarters. It is the same amount of money (or same date), but if you were expecting paper, and got metal, you would be confused.
How to convert
Luckily the Timestamp object has functions built into do give you a Javascript Date object: toDate
Note: Remember, toDate looks like the Javascript toLocaleDateString() or toDateString() but it is not. A JS Date() object and Firestore Timestamp object are not the same so don't make my rookie mistake of trying to use functions from one, on the other.
To convert a Firestore Timestamp into a Javascript date, just call .toDate() on the Timestamp.
//get the document from Firestore
let fireStoreTimestamp = doc.data().nameOfYourDateField;
let javascriptDate = fireStoreTimestamp.toDate();
You can use the dayjs library to convert firebase firestore timestamp seconds to your local time.
newDate = dayjs.unix(date.seconds).$d;
It will take
date: {
seconds: 1639506600,
nanoseconds: 0
}
and convert it to
Date Sat Nov 16 2019 00:00:00 GMT+0530 (India Standard Time)
To help those still looking around for an answer to convert Firestore Date to JS Date to display in the web app. Here goes an example using typescript...
import {
Timestamp,
} from "firebase/firestore";
interface IStuff {
createdAt: Timestamp;
}
const insertStuff = async (text: string) => {
await addDoc(collection(db, "coolstuff"), {
text,
createdAt: serverTimestamp(),
});
};
<p>{item.createdAt?.toDate().toDateString()}</p>
// OR
<p>{item.createdAt?.toDate().toLocaleTimeString()}</p>
Extending Waleed Tariq answer, to get a more readable string:
function formatDate(date) {
const formatDate = new Date(
date.seconds * 1000 + date.nanoseconds / 1000000
);
return formatDate.toLocaleTimeString('en-us', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' });
}
const timeStamp = {nanoseconds: 184000000, seconds: 1664826910};
console.log(formatDate(timeStamp))
I had the same problem. And i figured out like this:
const createdAt = firebase.firestore.Timestamp.fromDate(new Date());
// then using dayjs library you can display your date as you want.
const formatDate = dayjs.unix(createdAt.seconds).format('YYYY-MM-DD');
Output should look like e.g. 2020-08-04
If you want don't want to lose the milliseconds you can do the following:
var myDate = a.record.dateCreated;
new Date((myDate.seconds + myDate.nanoseconds * 10 ** -9) * 1000);
i work in angular.
i have an interface and a field date: Date.
the angular pipe date no work: order.date | date:'medium'
i change type of field date in interface
date: firebase.firestore.Timestamp
the angular pipe date work, but with function toDate()
order.date.toDate() | date:'medium'
It's very simple really. Use this simple epoch converter function which converts epoch seconds into Javascript date and time.
function getUNIXTime(dt) {
let unix = new Date(dt * 1000);
return unix.toUTCString().slice(5, 16);
}
Pass the timestamp.seconds into this function then slice it according to your needs to get a string of text with date and time.
Normally using any type (i.e. loginDate:any) and toDate() worked without problem in my all projects. But in my last project it didn't. I saw seconds in Timestamp object is _seconds anymore (Firebase 8.6.8). This type of change may have affected it. I don't know but i had no time so i used an alternative solution. A custom pipe. It can be used as an alternative:
import { Pipe, PipeTransform } from '#angular/core';
import { formatDate } from '#angular/common';
#Pipe({
name: 'timestamp'
})
export class TimestampPipe implements PipeTransform {
transform(value: any, format?: string) {
if (!value) { return ''; }
if (!format) { format = 'dd MMM yy'; }
return formatDate(value._seconds * 1000, format, 'tr');
}
}
and
{{ item.endDate | timestamp}}
P.S. Type is not important with this pipe. Worked with loginDate:any or loginDate:Date well.
to store timestamp into firestore:
import * as firebaseAdmin from "firebase-admin";
const created = firebaseAdmin.firestore.FieldValue.serverTimestamp();
// type
created: FirebaseFirestore.Timestamp | FirebaseFirestore.FieldValue | undefined;
To read back as a js Date object
const createDate = (created as FirebaseFirestore.Timestamp).toDate();
To read back as RFC3339 string
const createDate = (created as FirebaseFirestore.Timestamp).toDate().toISOString();
Web Firestore Timestamp:
function dateToFirestoreTimestamp(dateString = ''){
var timestampDate = new Date(); // this will return current date-time
if(dateString != ''){
// this will return timestamp according to provided date-time
dateString = dateString.replace(' ', 'T');
timestampDate = new Date(dateString);
}
timestampDate = firebase.firestore.Timestamp.fromDate(timestampDate);
return timestampDate;
}
This is by far the most elegant, precise and easiest way to convert a firebase-timestamp to a date (no dependenceis etc. needed)
const date = new Intl.DateTimeFormat(
'de-De', {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric'
}
).format(firebaseTimeStamp.toDate())
Here is a cheatsheet with all necesarry parameters
this is the different thing between firestore timestamp and Javascript Date() object. if you want to use javascript Date() object from firestore timestamp, this is what I do:
const foo = new Date(firestoreTimestamp.toDate());
then you can use the javascript Date() object, as usual. here are some references:
https://www.w3schools.com/jsref/jsref_obj_date.asp
For example, we want to retrieve the date from the Date() object with string format:
const foo = new Date(firestoreTimestamp.toDate());
foo.toLocaleDateString();
etc.
I have two variables in javascript like:
time: 02:00
date: 25-08-2017
and I'm wondering if I can put these into a Date() object and get the UTC date and time out of it in hours/minutes using getUTCDay(), getUTCHours() and getUTCMinutes() and place them back in the format I got them.
I can load moment.js for it but if I don't have to it would be nice if I can do it without.
Convert your strings to an ISO 8601 string and use it in the Date constructor. From there, you can get whatever data you need
let time = '02:00'
let date = '25-08-2017'
let iso8601Date = date.split('-').reverse().join('-')
let dt = new Date(`${iso8601Date}T${time}`) // will be interpreted as local time
const digitFormatter = new Intl.NumberFormat(undefined, {minimumIntegerDigits: 2})
console.info('Parsed date:', dt)
console.info('UTC date in dd-mm-yyyy:',
`${digitFormatter.format(dt.getUTCDate())}-${(digitFormatter.format(dt.getUTCMonth() + 1))}-${dt.getUTCFullYear()}`
)
console.info('UTC time:', `${digitFormatter.format(dt.getUTCHours())}:${digitFormatter.format(dt.getUTCMinutes())}`)