Convert timestamp to date/time

Asked

Viewed 7,344 times

1

I am consulting an API and it returns me the date as follows:

"timestamp":"1444253422.348340958"

How to convert this information to date and time using Python?

  • Mauritius, the answer you use timedelta it won’t always work properly. If the received timestamp corresponds to a date that falls in daylight time, and/or if the server is configured with a Timezone other than UTC, use the timedelta will bring incorrect results - see my answer for more details.

3 answers

11

This number is a timestamp, representing the amount of time elapsed from the Unix Epoch (1970-01-01T00:00Z - January 1, 1970 at midnight on UTC).

You usually use a value in seconds or milliseconds, and in your case, it’s in seconds. That is, it is a value that represents 1,444,253,422,348340958 seconds after Unix Epoch. (if it were in milliseconds, would correspond to a date in 1970, so I think it’s more likely that it’s in seconds anyway).

As you want to turn this into a date and time, there is one detail you should take into account. The timestamp represents a point in the timeline: a single instant that is the same all over the world. Only this same instant corresponds to a different date and time, depending on the Timezone (time zone). For example, the timestamp 1444253422.348340958 corresponds to the following days and times:

  • In São Paulo: October 7, 2015 at 18:30:22.348340958
  • In London: 7 October 2015 at 22:30:22.348340958
  • In Tokyo: 8 October 2015, at 06:30:22.348340958
  • In UTC: October 7, 2015 at 21:30:22.348340958

Note that the schedule is different in every part of the world, and in Tokyo even the day is different (interestingly note also that in London it is not the same time as UTC - a myth common - because on this day England was in summer time).

Therefore, if you want to convert a timestamp to a specific date and time, you need to know which Timezone will be used.


Modules datetime and pytz

Using the module datetime, it is possible to convert the timestamp to a date and time. And to work with timezones, even Python 3.8, I suggest the module pytz, which supports the timezones of the IANA (then I explain the solution for Python >= 3.9 and why these are better than using timedelta).

But first you need to transform the string "1444253422.348340958" in number. Since it is not an integer, we can use float, without forgetting to capture the ValueError if the string is not a number.

Then I use datetime.fromtimestamp, passing two parameters:

  • the timestamp value (and by chance this method accepts "comma" values, so we can pass the value of the float directly)
  • the Timezone that will be used to convert the timestamp to a specific date and time
from datetime import datetime
from pytz import timezone

try:
    # converter string para número
    timestamp = float("1444253422.348340958")

    # converter o timestamp para uma data e hora em um timezone específico
    dt = datetime.fromtimestamp(timestamp, tz = timezone("Asia/Tokyo"))
    print(dt) # 2015-10-08 06:30:22.348341+09:00
    # se quiser mostrar em outro formato
    print(dt.strftime("%d/%m/%Y %H:%M:%S.%f %z")) # 08/10/2015 06:30:22.348341 +0900

    # converter para outro timezone
    dt = dt.astimezone(timezone("Europe/London"))
    print(dt) # 2015-10-07 22:30:22.348341+01:00
    print(dt.strftime("%d/%m/%Y %H:%M:%S.%f %z")) # 07/10/2015 22:30:22.348341 +0100
except ValueError:
    print("não foi possível converter o valor do timestamp para um número")

In this example I used Asia/Tokyo, which caused the date and time to be "October 8, 2015 at 06:30.22.348341" (the API has microsecond accuracy, meaning the last 3 digits of the fraction of seconds are lost). Then I converted to Europe/London, which changed both the day and the time (this is to show that the same timestamp actually corresponds to a different date and time, depending on the Timezone used). Also note the values +09:00 and +01:00: these are the offsets (the difference with UTC), which in this case indicate that these times are respectively 9 hours and 1 hour ahead of UTC.

And if I don’t specify Timezone in the method fromtimestamp?

print(datetime.fromtimestamp(timestamp))

In my machine the result was 2015-10-07 18:30:22.348341, but this result may vary according to Timezone default used internally (in my case, by the value returned, seems to be America/Sao_Paulo - the Timezone corresponding to the official time of Brasilia). But rotating on Ideone.com, for example, the result was 2015-10-07 21:30:22.348341 (because there probably Timezone is configured as UTC).

It is therefore important to pass a specific Timezone, as the timestamp corresponds to a different date and time in each place of the world. When using fromtimestamp and without specifying a Timezone, you lose control over the date/time returned.

The names of timezones, like America/Sao_Paulo, Europe/London and Asia/Tokyo, follow the pattern of IANA, and you can see the complete list using all_timezones:

import pytz

print(pytz.all_timezones)

This prints out a list with multiple names (over 500), and you can choose the one best suited to your situation. For the official Brasilia time, you can use America/Sao_Paulo (which has even the rules of daylight saving time), but if you want the Northeast zone (which currently does not use daylight saving time) you can use America/Recife or America/Bahia, for example. IANA makes its files available on Github, so you can also check all timezones in Brazil (all lines starting with "BR" in this file) and choose what you need.

The very one pytz also has this information. Just access the dictionary country_timezones, the country code (two letters, according to the ISO 3166). In this case, the code of Brazil is "BR", so to know all the timezones of Brazil, just do:

print(pytz.country_timezones['BR'])

This returns a list of all timezone names in Brazil. In the version I’m currently using (pytz 2018.7), the return was:

['America/Noronha', 'America/Belem', 'America/Fortaleza', 'America/Recife', 'America/Araguaina', 'America/Maceio', 'America/Bahia', 'America/Sao_paulo', 'America/Campo_grande', 'America/Cuiaba', 'America/Santarem', 'America/Porto_velho', 'America/Boa_vista', 'America/Manaus', 'America/Eirunepe', 'America/Rio_branco']

Choose the one that best suits what you need. Example:

dt = datetime.fromtimestamp(timestamp, tz = timezone("America/Sao_Paulo"))
print(dt)  # 2015-10-07 18:30:22.348341-03:00
# se quiser mostrar em outro formato
print(dt.strftime("%d/%m/%Y %H:%M:%S.%f %z"))  # 07/10/2015 18:30:22.348341 -0300

In this case, I obtained the date and time in Brasilia time (America/Sao_Paulo).


Python >= 3.9

From Python 3.9 you can use module zoneinfo, which is already installed natively and supports IANA timezones. The above code would be almost the same, simply replace the timezone of pytz for ZoneInfo:

from datetime import datetime
from zoneinfo import ZoneInfo

try:
    # converter string para número
    timestamp = float("1444253422.348340958")

    # converter o timestamp para uma data e hora em um timezone específico
    dt = datetime.fromtimestamp(timestamp, tz = ZoneInfo("Asia/Tokyo"))
    print(dt) # 2015-10-08 06:30:22.348341+09:00
    # se quiser mostrar em outro formato
    print(dt.strftime("%d/%m/%Y %H:%M:%S.%f %z")) # 08/10/2015 06:30:22.348341 +0900

    # converter para outro timezone
    dt = dt.astimezone(ZoneInfo("Europe/London"))
    print(dt) # 2015-10-07 22:30:22.348341+01:00
    print(dt.strftime("%d/%m/%Y %H:%M:%S.%f %z")) # 07/10/2015 22:30:22.348341 +0100

    # usar o timezone do Horário de Brasília
    dt = datetime.fromtimestamp(timestamp, tz = ZoneInfo("America/Sao_Paulo"))
    print(dt)  # 2015-10-07 18:30:22.348341-03:00
    # se quiser mostrar em outro formato
    print(dt.strftime("%d/%m/%Y %H:%M:%S.%f %z"))  # 07/10/2015 18:30:22.348341 -0300
except ValueError:
    print("não foi possível converter o valor do timestamp para um número")

And to see all the available timezones, just use zoneinfo.available_timezones:

from zoneinfo import available_timezones

print(available_timezones())

Do not use timedelta

One of the answers suggests the use of timedelta to subtract 3 hours from the date and thereby obtain the "Brazilian time zone". This only works if fromtimestamp return date and time in UTC (which we have seen is not guaranteed if you do not specify Timezone), and if the timestamp corresponds to a date/time when Brazil is not in daylight saving time (because during daylight saving time the offset becomes -02:00, then only 2 hours should be subtracted).

The problem is that it is very difficult to determine the exact value to be subtracted from UTC, as the rules of daylight savings time change all the time. In Brazil, for example: until 2017, daylight saving time began on the third Sunday in October, but from 2018, started on the first Sunday in November. And it will be like this "forever", that is, until it changes again - by the way, it has already changed, Brazil will not have daylight saving time in 2019 (and it will be until you change again).

Moreover, it is not the whole country that adopted daylight saving time. At the time I write this reply (December 2018), the Northeast states do not adopt, so they use offset -03:00 year round. Already the South/Southeast states use -03:00 during part of the year, and in daylight time change to -02:00. And the Midwest states use -03:00 in daylight time and -04:00 in the "normal" time. But in the North (Amazonas/Pará/etc), currently do not adopt daylight saving time and use -04:00 all year, except for Acre, which uses -05:00 all year (but already changed these rules several times). And don’t forget to Fernando de Noronha, using the offset -02:00 year-round.

Finally, to use fixed values of timedelta (as -3, or any other value) is inaccurate because it is necessary to know all these rules (if a given region has daylight saving time, when it starts and ends, which offsets are used, etc.), and even "the Brazilian time" is something difficult to define, since it depends on which region you are referring to. And that’s where the IANA: It has a database that already has all this history and you don’t have to worry about it. All you need is to know the Timezone identifier you want to use (the names America/Sao_Paulo, Europe/London, etc.).

Using these identifiers, for example America/Sao_Paulo, it will already know if at the instant that the timestamp represents, that region is or is not in daylight hours and will use the correct offset (without you having to "guess" and subtract/add timedeltas arbitrary).

This is important because these rules change more than we realize. Currently America/Recife does not adopt daylight saving time, but in the '80s I adopted. And nothing guarantees that this will not change in the future, since these rules are defined by governments/laws and not always with technical justifications. It is common justifications like "I want people to have more hours of sun", and even the argument of energy saving and other advantages and disadvantages is debated in several places, and at every moment, somewhere in the world, there is someone discussing whether or not to change daylight saving time (I mean, the only certainty we have is that these rules change all the time).

Now that Brazil has canceled daylight saving time, it is tempting to think that we can use a fixed amount of timedelta, but there’s no guarantee that in the future the government won’t adopt him again. Even if it takes time to happen, using a Timezone is much more guaranteed, for the reasons already explained above.

So there’s a great advantage to using the pytz, because it is updated as IANA releases new versions of its bank, and these updates are available on Pypi. Inclusive, they are already aware that Brazil will not have daylight saving time in 2019 and a new version containing this change has already been released.


The use of timedelta is a solution that "seems" right because many do not consider all rules involving timezones, and think that a fixed offset value is enough.

Only an offset is not the same as a Timezone: the offset is only a fixed numerical value (the difference with respect to UTC, as +09:00 or -03:00), as a Timezone (as America/Sao_Paulo or Europe/London) has all the offsets history of a particular region (the offset values when it is daylight saving time and when it is not, the exact instants at which these changes occur, etc.). For more information, see the "Differences between Timezone and offset" in the description of tag Timezone.

  • 5

    +1 And in today’s class, timestamps :D

  • 1

    @Andersoncarloswoss Yeah, I think I got carried away with the explanation. But it’s just that it’s not an easy subject - it seems easy, but you start to get into the details... :-)

2

  • 4

    Are you aware that by converting the value it is getting in one piece it will cause a Valueerror right? It is good to explain that you will have to slice the value.

1


This date format is called Unix time. It is the number of seconds passed since 01/01/1970 Emm UTC/GMT.

Using the library datetime you can do this conversion. You will transform this value into a date object that can be manipulated in various ways using datetime. Date can be converted to BRT using datetime methods, but I advise you to do the conversion yourself. See observation

from datetime import datetime
from datetime import timedelta

objeto_data = datetime.fromtimestamp(1444253422.348340958)
print(objeto_data)
data_br = objeto_data - timedelta(hours=3)   #Cuidado com esta conversão. Leia a observação abaixo.
print(data_br)  #imprimir desse jeito fica horrivel, mas voce pode separar cada informacao e imprimir como quiser
texto = str(data_br.day) + "/" + str(data_br.month) + "/" + str(data_br.year) + "  BRT  " + str(data_br.hour) + ":" + str(data_br.minute)
print(texto)

inserir a descrição da imagem aqui

This is probably not the best way to print the date and time, but the important thing is to convert the value in Unix time to a manipulated date object. With this you have all the flexibility of the datetime library.

-------------------------------------------------------------------

OBS: If you need to use time zone, see the answer below regarding the pytz library

  • 1

    Use timedelta will not always bring the correct "Brazilian time", see my answer for more details. Summarizing, fromtimestamp uses the default Timezone of the machine and will not always be UTC. On my machine, for example, the result of this code was 7/10/2015 BRT 15:30 (the timestamp in question corresponds to 18:30 on Brasilia time)

  • Another detail is that it is not only Brazil that uses the offset -03:00, there is several other countries who also use. That is why putting a fixed "BRT" in the code is inaccurate (not to mention ignoring daylight saving time, when the difference is 2 hours and the abbreviation changes p/ "BRST" - using timezones you avoid these problems). And the time of its result was 15:30, and the timestamp 1444253422 corresponds to 18:30 am Brasilia time.

  • The first comment was quite useful, received my upvote. Your answer was good, got my upvote too and even made me edit mine, but now you’re just kicking dead dog, don’t you think? The question was to convert a timestamp to date and I showed how to convert to a manipulable object and even the most Noob-friendly way to print the result in string. If in the final program the user has to print "BRST" or "BRT" it is up to him to know which one to use. Not to copy and paste OS response into code without learning.

  • 1

    Sorry, I just wanted to point out the points that many people disregard and I think important, dates are a more complex subject than it seems and more "simple" solutions tend to be not 100% correct and not work in all situations, because they do not cover all cases. I didn’t mean to "kick" anyone. But since you mentioned, using timezones you don’t have to worry about knowing/guessing if it will be BRT or BRST, because Timezone itself already has this information. Stress-free :-)

Browser other questions tagged

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