Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

google.protobuf.Timestamp #437

Closed
marshauf opened this issue May 31, 2016 · 16 comments
Closed

google.protobuf.Timestamp #437

marshauf opened this issue May 31, 2016 · 16 comments

Comments

@marshauf
Copy link

Hello,

I would like to transfer a Javascript Date object. It seem google.protobuf.Timestamp is the 'standard' way of formatting it. Is it possible to register a decode/encode function on the Timestamp message, so that I can convert JS Date to Timestamp and back?

@dcodeIO
Copy link
Member

dcodeIO commented May 31, 2016

Reference: https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto

Looks like this is just a wrapper for "seconds of UTC time since Unix epoch". It should be safe to include this file in your project and to work with Timestamp#seconds.

Minimal proto:

syntax = "proto3";
package google.protobuf;
message Timestamp {
  int64 seconds = 1;
  int32 nanos = 2;
}

@marshauf
Copy link
Author

marshauf commented Jun 1, 2016

I would like to do the following.

message User {
  google.protobuf.Timestamp created = 1;
}
var user = {
created:Date.now(),
}
var b = new User(user).encode();

Without the need to do something like the following on each Date object.

var now = Math.floor(Date.now().getTime()/1000);
var user = {
created:{seconds:now},
}

Can I register a encode/decode function to the Timestamp message?

@baddev89
Copy link

baddev89 commented Apr 8, 2018

I now this was closed but wanted to know if you found a solution? I'm trying to do the same thing of using a Timestamp message and can't find a way to make it work. Thanks.

@klingenm
Copy link

I'm also wondering about this; Looking at Google's own implementation the JSON representation of the google.protobuf.Timestamp message type is the string representation...

From https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto

JSON Mapping

// In JSON format, the Timestamp type is encoded as a string in the
// RFC 3339 format. That is, the
// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
// where {year} is always expressed using four digits while {month}, {day},
// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
// is required. A proto3 JSON serializer should always use UTC (as indicated by
// "Z") when printing the Timestamp type and a proto3 JSON parser should be
// able to accept both UTC and other timezones (as indicated by an offset).
//
// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
// 01:30 UTC on January 15, 2017.
//
// In JavaScript, one can convert a Date object to this format using the
// standard toISOString()
// method. In Python, a standard datetime.datetime object can be converted
// to this format using strftime
// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
// can use the Joda Time's [ISODateTimeFormat.dateTime()](
// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
// ) to obtain a formatter capable of generating timestamps in this format.
//

@yaelz
Copy link

yaelz commented Feb 21, 2019

Can this be reopened? Can't make it work :-|

@datoml
Copy link

datoml commented Mar 19, 2019

Can this be reopened? Can't make it work :-|

Hey.
I hope I am not too late but you can do something link this.

if (window.proto) {
  const proto = window.proto;
  const timeMS = Date.now();
  
  // Create timestamp
  const timestamp = new proto.google.protobuf.Timestamp()
  timestamp.setSeconds(timeMS / 1000);
  timestamp.setNanos((timeMS % 1000) * 1e6);
}

@Jeff-Tian
Copy link

Jeff-Tian commented May 16, 2019

I can not use timestamp.setSeconds and timestamp.setNanos, so I used the following way:

const timestamp = google.protobuf.Timestamp.fromObject({
  seconds: timeMS / 1000,
  nanos: (timeMS % 1000) * 1e6
})

@jontroncoso
Copy link

Why was this closed? There was no explanation. Is this a won't fix? This still doesn't work.

@jontroncoso
Copy link

@marshauf can you reopen this?

@cs145442
Copy link

@jontroncoso
Timestamp Documentation mentions about the way it is structured. Following the same, in JavaScript, you can generate a timestamp with the below code.

new Date().toISOString()

@laszlo-horvath
Copy link

I also had some issues using the Timestamp in Typescript. Turned out it was because of setSeconds and setNanos.

The following code did the trick for me:

import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';

const timestamp = new Timestamp();
timestamp.fromDate(new Date());

Source: https://stackoverflow.com/a/58391603/787625

@claudiohs-inditex
Copy link

claudiohs-inditex commented Oct 13, 2021

I solved this issue using the below code in Javascript:

var d = new Date(timestamp.seconds.low);
d.setMilliseconds(timestamp.nanos / 1e6); 
console.log (d.toISOString());

@mkfsn
Copy link

mkfsn commented Mar 3, 2022

I also had an issue with setSeconds and setNanos and turns out I need to use Math.floor when calling setSeconds:

import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';

const timeMS = Date.now();

const timestamp = new Timestamp();
timestamp.setSeconds(Math.floor(timeMS / 1000)); // (timeMS / 1000) gives me a float number but setSeconds expects an integer
timestamp.setNanos((timeMS % 1000) * 1e6);

or using Timestamp.fromDate:

import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';

const timeMS = Date.now();

const timestamp = Timestamp.fromDate(new Date(timeMS));

@younessdev9
Copy link

@mkfsn I'm trying to do the opposite which is getting seconds and Nanos and converting them to valid JS dates or epoch time any Ideas ?

@mkfsn
Copy link

mkfsn commented Mar 8, 2022

@younessdev9 I see there are getter functions for seconds and Nanos, do you mean something like this?

import { Timestamp } from 'google-protobuf/google/protobuf/timestamp_pb';

function toDate(timestamp: Timestamp): Date {
    return new Date(timestamp.getSeconds()*1000 + timestamp.getNanos()/1e6);
}

@mbrowne
Copy link

mbrowne commented Dec 20, 2022

@claudiohs-inditex accessing timestamp.seconds.low directly isn't a safe approach... I think that will cause it not to work for dates far in the future where the number of seconds is higher than the max int32 value. I'm guessing that like me, you were trying to parse a raw timestamp object from this library, in which the seconds property is a Long object (from long.js. The Long class has several methods to convert it to a primitive value; I'm not an expert, but I think that toNumber() will give a reliably correct result. So this is what I ended up with:

new Date(
    timestamp.seconds.toNumber() * 1000 +
        timestamp.nanos / 1e6
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests