I am trying to get readable date from firestore - node.js

I am trying to get readable date from Timestamp data type in my firestore database.
for (var ticketDoc of ticketsSnapshot.docs) {
var timeStamp = await ticketDoc.data().TimePreferred;
console.log(timeStamp.toDate());
var time = new Date(timeStamp).toDate();
ticketDoc.data().TimePreferred = time;
tickets.push(ticketDoc.data());
}
I read the question about a similar problem at :
How do I convert a Firestore date/Timestamp to a JS Date()?
so, i tried to do same and i expect the output of readable date, although it gives me the correct result in
console.log(timeStamp.toDate());
but also it gives me an error. Console output as follow :-
2019-04-10T06:30:00.000Z
TypeError: (intermediate value).toDate is not a function
Not : I am trying to get readable date in postman

I don't know why this timestamp object doesn't have the .toDate() extension, but if it has the 'seconds' and 'nanoseconds' properties, you can turn it to a JS Data with
Date(data.seconds)

Change the following line:
var time = new Date(timeStamp).toDate();
into this:
var time = new Date(timeStamp).toDateString();
From the docs:
A string representing the date portion of the given Date object in human readable form in American English.

You can try in the following way
{{ formatDate(new Date(data.seconds*1000)) }}
You can use the format date function to display in desired format.
import moment from "moment";
format_date(value) {
if (value) {
return moment(String(value)).format("DD/MM/YYYY");
}
},

Have you tried changing this to
var time = (new Date(timeStamp)).toDateString();

If the TimePreferred field in your document is a Timestamp, you can get a valid Date object from it by simply calling toDate() on it.
So:
for (var ticketDoc of ticketsSnapshot.docs) {
var date = ticketDoc.data().TimePreferred.toDate();
}
None of these calls are asynchronous or returning a promise, so you don't need await.

From reasons that I don't know, it doesn't work at times, so a safer option would be to use the seconds and nanoseconds attributes found in the timestamp to convert it to date as follows:
const date = new Date(timestamp.seconds*1000 + timestamp.nanoseconds/100000)
// construct the date from the absolute time in milliseconds
Note:
1 second = 1000 ms
1 nanosecond = 10^-6 ms

You have to first make sure that the timestamp object is truly of type Timestamp.
to do this, after you get the Timestamp from Firebase, create the Timestamp object:
const timestampObject: Timestamp = !!timeStamp
? new Timestamp(timeStamp.seconds, timeStamp.nanoseconds)
: null;

For Angular
import { Location, DatePipe } from '#angular/common';
constructor(
public datepipe: DatePipe
) { }
const dayAsTimestamp = your_Timestamp_value;
const dayAsDate = new Date(dayAsTimestamp.seconds * 1000);
const dayAsString = this.datepipe.transform(dayAsDate, 'dd-MMM-yyyy');

Related

Day.js unable to properly format date input in nodejs and reactjs

I am trying to implement dayjs package in my node.js application. I would like my date and time to be formatted like this:
2022-09-11T17:46:00+01:00
I have my codes like this:
const dayjs = require("dayjs");
const utc = require("dayjs/plugin/utc");
const customParseFormat = require('dayjs/plugin/customParseFormat');
const dayJsUTC = dayjs.extend(utc)
const dayJsDate = dayJsUTC.extend(customParseFormat)
I am trying to check that the format comes out this way 2022-09-11T17:46:00+01:00
Here is the code:
if(!dayJsDate( 2022-09-11T17:46:00+01:00, "YYYY-MM-DD HH:mm", true).isValid()){
return res.status(500).json('invalid date')
}
It is returning invalid date. I know I am not doing it properly. How can I do it properly to scale this validation?
Also, if I want to simply create only date, hour and minute without the additional time details, how can I do that using dayjs?
Sorry for not answering your question straight, but you could get what you want by defining your own function. When you pass no args to it, it returns just time in format like you wish, when passing a string to function - it return true or false, checking format. If you pass second param as "true", function will return date, hours and minutes.
const myDate = (input, noSecondsAndOffset) => {
const
offset = -(new Date().getTimezoneOffset()),
offsetHours = '0' + offset / 60,
offsetMins = '' + offset % 60,
timeZone = `${offsetHours}:${offsetMins}${offsetMins.length === 1 ? '0' : ''}`,
currTime = `${new Date().toJSON().slice(0, -5)}+${timeZone}`,
checker = (string) => !!string.match(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+\d{2}:\d{2}/);
return typeof input === 'string'
? checker(string)
: !noSecondsAndOffset
? currTime
: currTime.slice(0, -9)
}

Convert google.protobuf.Timestamp to ISO format in Fabric 1.4 in NodeJS

I am running a Hyperledger Fabric 1.4 chaincode and try to retrieve the history of a key with getHistoryForKey stub method. I am iterating over each entry and want to convert them for standardization in all my chaincode functions.
Now, I can handle all keys in the iterator, except the timestamp which is a google.protobuf.Timestamp. Any tries of mine fail to convert it to an ISO datetime string.
Code
// Entry method to retrieve the full history of any asset
async (stub, args) => {
const idToSearch = args.id
const historyIterator = await stub.getHistoryForKey(idToSearch)
let historyData = []
await iterate(historyData, historyIterator)
if (historyData.length === 0) throw errors.ASSET_NOT_FOUND(idToSearch)
return historyData
}
// I use node v8 and thus cannopt use for await to iterator and must write recursive helper func
const iterate = async (historyData, historyIterator) => {
const element = await historyIterator.next()
if (!element) return historyIterator.close()
const {value} = element
if (!value) return historyIterator.close()
historyData.push({
value: value.value.toString('utf8'),
isDeleted: value.is_delete,
txId: value.tx_id,
timestamp: value.timestamp // <-- WANT TO CONVERT TO ISO DATE TIME STRING
})
await iterate(historyData, historyIterator)
}
My Approaches
1. toISOString()
Regarding the documentation of the protobuf of timestamp it says "In JavaScript, one can convert a Date object to this format using the standard toISOString()". This does not work, since I get "toISOString is not a function".
2. new Date()
Further, I tried to run new Date(protobufTimestamp), which results in "Invalid Date".
3. Using the seconds
I though maybe I can utilize the seconds which are on of two keys (Object.keys(protobufTimestamp) => [seconds, nanos]) in the timestamp to create the Date. But that date object also says "Invalid Date". That could be explained since I read that Protobuf Timestamp covers the ranges from year 0 to 9999. So, maybe the conversion fails.
Question
Can someone explain me how to convert the google protobuf timestamp to an ISO timestamp in Fabric 1.4 in NodeJS?
You can try something like
new Date(protobufTimestamp.seconds * 1000).toISOString()

moment-timezone: unix timestamps with timezones

i am using momentjs.com with nodejs and im trying to get unix timestamps for multiple timezones, but sadly the the output is not correct.
code:
var moment = require('moment-timezone');
var berlin = moment.tz('Europe/Berlin').unix();
var angeles = moment.tz('America/Los_Angeles').unix();
var london = moment.tz('Europe/London').unix();
console.log(berlin);
console.log(angeles);
console.log(london);
output:
1472241731
1472241731
1472241731
A Unix Timestamp is always UTC based. It is the same timestamp everywhere on the planet simultaneously.
Changing the time zone of a moment object using moment-timezone only affects the local time value, such as used with the format function (and others). It does not change the moment in time being represented, and therefore does not change the underlying timestamp.
you can use Date.parse to get a timestamp, like this
const moment = require("moment-timezone")
const time = '2022-09-02 04:06:25'
var a = new Date(time).valueOf()
var b = Date.parse(moment.tz(time, "America/Chicago").format())
console.log(a) // China 1662062785000
console.log(b) // Chicago 1662109585000
To show correct time to user for different timezone, we can add timezone offset to unix UTC timestamp
const convertToNewTimeZone = (timeInMilliseconds: number, timezone: string) => {
const utcOffset = moment.tz(timeInMilliseconds, timezone).utcOffset();
return moment(timeInMilliseconds)
.add(utcOffset, 'minutes');
};
Note that if you are calculating time in browser, you may have to subtract the browser timezone offset
newTime.clone().subtract(moment().utcOffset(), 'minutes')

Anything weird about dates in Entity Framework Linq queries?

I had a test case that looks like this:
[TestMethod]
public void Things_can_be_saved()
{
var ts = DateTime.Now;
var thing = new Thing()
{
Name = "Some name",
TimeStamp = ts
};
// save it
var context = new MyDataContext(testDb);
context.Things.Add(thing);
context.SaveChanges();
// pull from a fresh context so we know it's a db pull not cached
var context2 = new MyDataContext(testDb);
var fetched = context2.Things.FirstOrDefault(t => t.TimeStamp == ts);
Assert.AreEqual(thing.Name, fetched.Name);
}
So, when I run this, I can look in the DB and see 'thing' present in the db. I can see that the stored Timestamp column for it is equal to the value in the ts variable at runtime. But 'fetched' is null, indicating that EF can't find it in the FirstOrDefault query. Is there something I'm missing about DateTime equality?
You probably need to change your column in the database to be datetime2 instead of datetime
Also see this thread: DateTime2 vs DateTime in SQL Server

Adobe Air: convert sqlite's result [object Object] to String?

I am currently trying to do retrieve text from sqlite. I see that the amount of data requested do come correctly, but content, on the other hand, seems to be in an incorrect format. I've tried some conversion:
var data:Array = sqls.getResult().data;
var stData:String = String(data[0]);
Alert.show(stData); // <--- displays "[object Object]"
String conversion does not seem to do what I want. I simply want the text from the sqlite database. How can I convert the [object Object] to the correct string in this case?
Irrespective of what rows are returned (with(out)) specifying columns, unless the itemClass property of the SQLStatement is defined, it will always return an anonymous object. This is essentially how remoting works with AMF.
There are two things you can do (depending on the complexity of your project):
Specify an SQLStatement.itemClass - this will define & popuplate the results of the return with public accessors (either var or get/set) with the same name as the column name.
If left as anonymous - the column names are attached to the object in which you iterate the object just as you would if it was defined.
Super basic example:
//SQL table schema
CREATE TABLE accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
num INTEGER NOT NULL,
name TEXT NOT NULL,
last_update DATE
);
//Define an Account class:
public class Account {
public var id:int;
public var num:int;
public var name:String;
public var last_update:Date;
}
//A statement to execute to get all accounts returned as an array of "Account"
var statement:SQLStatement = new SQLStatement();
statement.sqlConnection = myConn;
statement.itemClass = Account;
statement.text = 'SELECT * FROM accounts';
statement.addEventListener(SQLEvent.RESULT, onResults);
statement.execute();
protected function onResults(event:SQLEvent):void
{
var statement:SQLStatement = SQLStatement(event.currentTarget);
var results:SQLResult = statement.getResult();
for each (var account:Account in results)
{
//do something useful like populate a model, grid, etc...
}
}
//Anonymous objects would iterate much the same way -when an item class isn't defined
protected function onResults(event:SQLEvent):void
{
var statement:SQLStatement = SQLStatement(event.currentTarget);
var results:SQLResult = statement.getResult();
for each (var account:Object in results)
{
//our 'Object' will have properties: id, num, name, last_update
//do something useful like populate a model, grid, etc...
}
}
Please try with Objectutil.toString(); function which converts an object of any kind to a string.

Resources