convert timestamp to pubnub timestamp of 17-digit precision unix time (UTC) - pubnub

I am trying to convert timestamp 2016-02-11 03:31:18 to pubnub timestamp of 17-digit precision unix time (UTC) something like 13406746780720711 given in reference url given by pubnub
I have tried following but no luck
function parseDateTime(s) {
var b = s.split(/\D/);
return new Date(b[0],b[1]-1,b[2],b[3],b[4],b[5])
}
date = new Date(parseDateTime("2015-02-11 02:10:54") / 10000);
console.log(date.getTime());//142360085
Above example gives output 142360085 which is 10 characters where pubnub asks for 17 digit timestamp.
Reason behind doing this is i want to fetch unread messages of particular user and send an email at EOD via email.
After converting mytimestamp to 17-digit precision unix time (UTC) i will pass it to pubnub history function and get unread messages.

Convert Unix Timestamp to PubNub Timetoken 17-digit Precision
Easy as pie: timestamp * 10000
Except for PHP. ❌ PHP ❌ does not support this level of integer precision! You can instead use String Concatenation and Coercion.
$tt = $unixtime_milliseconds . "0000";
Your unix time must be represented in millisecond precision, no fractions / no floats.
Try out this example using JavaScript.
// Vars
var timestamp = +new Date;
var unix_time = document.getElementById("unix-timestamp");
var pubnub_time = document.getElementById("pubnub-timetoken");
// Conversion
function unix_to_pubnub(time) {
return time * 10000;
}
// Update Time
unix_time.innerHTML = timestamp;
pubnub_time.innerHTML = unix_to_pubnub(timestamp);
<span id="unix-timestamp"></span> - Unix Timestamp <br>
<span id="pubnub-timetoken"></span> - PubNub Timetoken

In Android get Current TimeToken
static Long getCurrentHourToken() {
return (Calendar.getInstance().getTimeInMillis()) * 10000L;
}
static Long getBeforeHourToken(int hours) {
return (Calendar.getInstance().getTimeInMillis() - TimeUnit.HOURS.toMillis(hours)) * 10000L;
}

In iOS how you can get current timestamp. This is written for PubNub.
static func currentTimeInMilliSeconds()-> CUnsignedLongLong {
let currentDate = Date()
let since1970 = currentDate.timeIntervalSince1970
return CUnsignedLongLong(since1970 * 1000)
}

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)
}

toLocaleString() not converting time to correct string

So I have the below code, which does a bunch of conversions between dates/strings/moments, and it all seems to be converting properly until the line that calls .toLocaleString(), not sure why but it is converting 2022-05-04T17:00:00.000Z to 5/4/2022, 1:00:00 PM, although I believe it should be 5/4/2022, 5:00:00 PM.
let timezone = "Europe/Lisbon"
let currentDate = new Date() // initialize new date object
let localizedTime = moment.tz(currentDate, timezone) // convert it to a moment in the specified timezone
localizedTime.set({ h: 18, m: 0, s: 0 }) // set the hours to 18 (equivalent to 6PM or 18:00)
let postgresFormat = localizedTime.format() // format in a postgres identifiable way
console.log(localizedTime.format())
let convertedBack = moment.tz(postgresFormat, timezone) // convert from string stored in Postgres back to a moment object
console.log(convertedBack)
let localedProperly = convertedBack.toDate() // convert from a moment to a Date object
console.log(localedProperly)
let withLocale = localedProperly.toLocaleString("en-US", { timezone: timezone }) // try to format it in such a way that a client can read it in 'en-US' locale. The local will change dynamically based on the user's device.
console.log(withLocale)
Not sure how to fix this, any help is much appreciated :)

I am trying to get readable date from firestore

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');

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')

moment.js reverse .fromNow()

So i'm working with moment.js.
I see you can translate a date into a human-friendly format using moment().fromNow();
Is there a way to do the opposite?
For example, I want to turn this --> "2 weeks ago" into a normal date format or UNIX timestamp.
I sifted through the documentation but couldnt find anything. Any direction would help, thanks.
Depending on how complicated/different the input strings can be, you could do this:
//parse out the number and the duration
var inputString = "2 weeks ago";
var myRegExp = /^(\d+)\s(\w+)\sago$/;
var results = myRegExp.exec(inputString);
var num = results[1];
var duration = results[2];
moment().subtract(duration,num).toString() //or whatever format you prefer
Note this will work for input strings of the format "number duration ago".
Hope that helps!
In some cases .fromNow() returns string like "30+ days ago". The regex provided in above solution doesn't handle to parse that properly.
Here's the updated regex to handle that case:
var myRegExp = /^(\d+)\+?\s(\w+)\sago$/;
Here is the method that I used to reverse it for the current moment.js locale. I tested it on a few locales and it should work for every locale but it might not.
Change the last two .toString() functions to .valueOf() to get numerical values.
Moment actually doesn't have the week name data for all languages right now, so the function will assume that the string is a week if it could not find the value.
Some languages use translation functions instead of having built in values so the script will not work on those either! If you manually specify your language data then it should work.
//test en locale
moment.locale("en");
console.log(reversefromNow("5 days ago"));
console.log(reversefromNow("in 5 days"));
//test ja locale
moment.locale("ja");
console.log(reversefromNow("5 日前"));
console.log(reversefromNow("5 日後"));
function reversefromNow(input) {
let relativeLocale = JSON.parse(JSON.stringify(moment.localeData()._relativeTime));
let pastfutureObject = {
future: relativeLocale.future,
past: relativeLocale.past
};
delete relativeLocale.future;
delete relativeLocale.past;
//detect if past or future
let pastfuture;
for (const [key, value] of Object.entries(pastfutureObject)) {
if (input.indexOf(value.replace("%s", "")) != -1) {
pastfuture = key;
}
}
//detect the time unit
let unitkey;
for (const [key, value] of Object.entries(relativeLocale)) {
if (input.indexOf(value.replace("%d", "")) != -1) {
unitkey = key.charAt(0);
}
}
//if its not in the data, then assume that it is a week
if (unitkey == null) {
unitkey = "w";
}
const units = {
M: "month",
d: "day",
h: "hour",
m: "minute",
s: "second",
w: "week",
y: "year"
};
//Detect number value
const regex = /(\d+)/g;
let numbervalue = input.match(regex) || [1];
//Add if future, subtract if past
if (pastfuture == "past") {
return moment().subtract(numbervalue, units[unitkey]).valueOf();
} else {
return moment().add(numbervalue, units[unitkey]).valueOf();
}
}

Resources