Convert the timestamp result to the formed Date and Time

Asked

Viewed 3,264 times

0

I need to convert the timestamp result (eg 121242343543) to the format 2018-11-09T16:36:01.

Controller.js:

function salvar() {

    var dataBase = new Date().getTime();

    // salva no banco
    var simulacao = {
        cpfCnpj : vm.cpfcnpj,                   
        dataBase : dataBase             
    };

    LaminaService.save(simulacao).then(function() {
        vm.lamina.sucesso = vm.messageService.getA('MA005');
    });

}   

In the entity Simulacao.java:

@Column(name = Constants.TS_SIMULACAO, nullable = false)
private LocalDateTime dataBase;

2 answers

2

I saw that your Java class is using a LocalDateTime, then there are some details to be attentive, before leaving by doing whatever conversion. I already say that I do not know the details of how Angular works, but I thought it pertinent to explain a little about dates and timestamps, so you know what you are doing when converting the date.

A timestamp is a number that represents the time elapsed from the Unix Epoch. Basically, the Unix Epoch is defined as the "Zero Instant", and the timestamp is nothing more than an amount of time that elapsed after (or before) it.

The value of Unix Epoch is 1970-01-01T00:00Z (January 1, 1970, midnight, in UTC). Detail for the Z in the end, that indicates that the date/time is in UTC. Many ignore this "Z" or think it is not important, but it makes all the difference (with it, we know that the date/ time is in UTC, without it, we have no way to state anything - unless there is some additional context).

The value of timestamp is usually the amount of seconds or milliseconds (also known as "thousandths of a second"), varies depending on the implementation/language/API. How did you use the new Date().getTime() javascript, the value returned is the amount of millisecond.

Well, the detail of the timestamp is that he’s the same all over the world. At the time I wrote this reply, the returned timestamp was 1541808475424 (or 1,541,808,475,424 milliseconds after Unix Epoch). This value is the same anywhere in the world: any computer that would have obtained the value of the timestamp at the same time as me, no matter where I am, would have the same value. Therefore, the timestamp represents a specific point in the timeline, a single instant.

Only this same timestamp value can mean a different date and time depending on the time zone used. In this case, the timestamp 1541808475424 may correspond to the following days and times:

  • In São Paulo: November 9, 2018, 22:07:55,424 (Ten on the evening of the 9th)
  • In Los Angeles: November 9, 2018, 16:07:55.424 (evening 4 of the 9th)
  • In Berlin: 10 November 2018 at 01:07:55.424 (one in the morning of the 10th)
  • In UTC: November 10, 2018, 00:07:55.424 (midnight of the 10th)

That is, the same timestamp value may correspond to a different date and time, depending on the Timezone (time zone) you use as reference. It makes sense, because now, at this very moment, in every part of the world, today and the present time are not necessarily the same here (the old story of "It’s already New Year in Australia", or even "It’s always happy-hour in some of the world").


Why am I saying all this?

Because in Java the class LocalDateTime has the date and time fields (day, month, year, time, minute, second and fractions of a second), but has no information about Timezone.

If I create one LocalDateTime whichever:

// 9 de novembro de 2018, 10:30 da manhã
LocalDateTime dataHora = LocalDateTime.of(2018, 11, 9, 10, 30);

This LocalDateTime represents "November 9, 2018, 10:30 am". But this class does not know which Timezone it is in, so it cannot be mapped to a single timestamp value. " November 9, 2018, 10:30 am" in Sao Paulo took place at a different time from "November 9, 2018, 10:30 am" in Berlin. Depending on the chosen Timezone, this LocalDateTime will result in a different timestamp.

So the conversion from timestamp to date/time is not that simple. You need to define which Timezone to use.

From what I understand, you’re creating the variable dataBase in Javascript and moving to Java. You said the variable needs to be in ISO 8601 format (is the name of the format you requested: 2018-11-09T16:36:01). And as you want the current date, just use new Date(). No need to call getTime() to obtain the timestamp, then to obtain the Date again. Use the Date directly and the method toISOString(), which returns the date in the desired format:

// data atual
let data = new Date();
console.log(data.toISOString());

If you really need to create a Date from the timestamp, do new Date(timestamp) as suggested the @fernandosavio.

The detail is that toISOString() returns the value of the timestamp converted to UTC (in addition to returning the fraction of seconds you said you don’t need). That is, the date and time will be in UTC (which may not be the time zone you need), and in addition you will have the Z at the end (and then I don’t know what exactly you’re using to turn this string into a LocalDateTime, then it may cause some problem in the conversion).

Of course you can remove the Z in the "ugly way" (data.toISOString().replace('Z', '')), and which I don’t particularly like because it removes important information. Knowing that the date/time is in UTC gives us confidence to convert it to the correct value of timestamp. If I do not know that that date/time is in UTC, it can be in any Timezone, and therefore can correspond to several different values of timestamp. But if you’re hopeless, remove the Z and try to get around the problem at the other end...

Another detail is that toISOString() also returns the fraction of seconds. If you want to remove it along with "Z", you can do data.toISOString().replace(/\.\d{3}Z$/, '').


Another alternative in Javascript is to use the library Moment js., together with the Moment Timezone (an extension to work with timezones). With this you can get the current date/time in a specific Timezone:

// data/hora atual no timezone de São Paulo
let now = moment().tz("America/Sao_Paulo")
// formato ISO 8601
console.log(now.format('YYYY-MM-DD[T]HH:mm:ss'));

// usando um valor de timestamp e convertendo para o timezone de São Paulo
let dt = moment.tz(1541808475424, "America/Sao_Paulo")
// formato ISO 8601
console.log(dt.format('YYYY-MM-DD[T]HH:mm:ss'));
<script src="https://momentjs.com/downloads/moment.min.js"></script>
<script src="https://momentjs.com/downloads/moment-timezone-with-data.min.js"></script>

With this, the date and time values will be converted to the Timezone you need. If you also want to return fractions of a second, change the format to YYYY-MM-DD[T]HH:mm:ss.SSS.

Timezone names follow the format "Continent/Region" (as America/Sao_Paulo, Europe/Berlin etc) as defined in IANA. To know all the available timezones, just use moment.tz.names().

This way you control exactly the Timezone that will be used and pass the correct date and time values in the parameter.


As I said at the beginning, I don’t know the details of how Angular works, nor how the string created in Javascript will be converted to LocalDateTime. Anyway, to convert a timestamp to a specific date/time you need to keep in mind all the above details.

Many languages and Apis hide this complexity simply by choosing some "standard" Timezone under the table, and then you end up with "wrong" dates and/or times without knowing the reason. Using the right tools (in this case, a specialized lib) allows you to have more control over the timezones used and have fewer surprises when working with the dates.

If I find more details about how Angular handles dates, I update the answer.

1


The builder of Date can receive a timestamp, then just extract the information you want to a string or the ready methods like the toISOString.

Example:

let timestamp = 1544380561000; // 09/12/2018 18:36:01
let data = new Date(timestamp);

console.log(data.toISOString());

  • The detail is that toISOString() returns the date/time in UTC, and it’s not clear to me if that’s exactly what AP needs. I detail this in my answer (unfortunately I could not give more details for not knowing how Angular deals with dates)

  • In my case it was just a hint of what can be done, it can extract the information you need from the Date object. toISOString was just an example. I did not intend to enter Timezone or anything like that. Your reply is more complete than I intended in my. :)

  • Oh yes, I didn’t mean your answer was wrong. She does what was asked (convert timestamp to ISO format), so much so that I gave +1 :) I just thought it was worth detailing more (and I ended up with a giant answer... ) :)

  • 1

    I would even go into detail, but your answer is already very good. I’ll leave mine to the lazy ones. Hahahaha

  • @fernandosavio, the solution worked perfectly. I just incremented the hkotsubo, where I put (date.toISOString().replace(/. d{3}Z$/, ')) closing in seconds (2018-11-12T12:09:23). Thank you all!

  • @hkotsubo, thanks for the support. I implemented Fernando’s initial solution by increasing your suggestion (date.toISOString().replace(/. d{3}Z$/, ')). It worked perfectly. Thank you!

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.