How can one convert a serial date number, representing the number of days since epoch (1970), to the corresponding date string? I have seen multiple posts showing how to go from string to date number, but I haven't been able to find any posts on how to do the reverse.
For example, 15951 corresponds to "2013-09-02".
>>> import datetime
>>> (datetime.datetime(2013, 9, 2) - datetime.datetime(1970,1,1)).days + 1
15951
(The + 1 because whatever generated these date numbers followed the convention that Jan 1, 1970 = 1.)
TL;DR: Looking for something to do the following:
>>> serial_date_to_string(15951) # arg is number of days since 1970
"2013-09-02"
This is different from Python: Converting Epoch time into the datetime because I am starting with days since 1970. I not sure if you can just multiply by 86,400 due to leap seconds, etc.
Use the datetime package as follows:
import datetime
def serial_date_to_string(srl_no):
new_date = datetime.datetime(1970,1,1,0,0) + datetime.timedelta(srl_no - 1)
return new_date.strftime("%Y-%m-%d")
This is a function which returns the string as required.
So:
serial_date_to_string(15951)
Returns
>> "2013-09-02"
And for a Pandas Dataframe:
df["date"] = pd.to_datetime(df["date"], unit="d")
... assuming that the "date" column contains values like 18687 which is days from Unix Epoch of 1970-01-01 to 2021-03-01.
Also handles seconds and milliseconds since Unix Epoch, use unit="s" and unit="ms" respectively.
Also see my other answer with the exact reverse.
Related
My code is the following:
date = datetime.datetime.now()- datetime.datetime.now()
print date
h, m , s = str(date).split(':')
When I print h the result is:
-1 day, 23
How do I get only the hour (the 23) from the substract using datetime?
Thanks.
If you subtract the current date from a past date, you would get a negative timedelta value.
You can get the seconds with td.seconds and corresponding hour value via just dividing by 3600.
from datetime import datetime
import time
date1 = datetime.now()
time.sleep(3)
date2 = datetime.now()
# timedelta object
td = date2 - date1
print(td.days, td.seconds // 3600, td.seconds)
# 0 0 3
You're not too far off but you should just ask your question as opposed to a question with a "real scenario" later as those are often two very different questions. That way you get an answer to your actual question.
All that said, rather than going through a lot of hoop-jumping with splitting the datetime object, assigning it to a variable which you then later use look for what you need in, it's better to just know what DateTime can do since that can be such a common part of your coding. You would also do well to look at timedelta (which is part of datetime) and if you use pandas, timestamp.
from datetime import datetime
date = datetime.now()
print(date)
print(date.hour)
I can get you the hour of datetime.datetime.now()
You could try indexing a list of a string of datetime.datetime.now():
print(list(str(datetime.datetime.now()))[11] + list(str(datetime.datetime.now()))[12])
Output (in my case when tested):
09
Hope I am of help!
The question in the title seems to be familiar as I could see lot of example blog posts and SO posts. However, I couldn't find a question similar to the issue I am facing. I have a netcdf file in which variable time has a single data value 10643385. The unit of this time variable is minutes since 2000-01-01 00:00:00 which is different from many examples I found on the internet.I am also aware of the fact that actual value of time is 27-03-2020 05:45. My query is that how do I get this epoch value int to the date time format like `27-03-2020 05:45'. Here is the sample code I have been trying which results in the reference datetime rather than actual datetime of the file:-
print(datetime.datetime.fromtimestamp(int(epoch_time_value)).strftime('%Y-%m-%d %H:%M:%S'))
The above single line of code result in 1970-05-04 09:59:45. Can some one help me to get the correct date.
import datetime
t = datetime.datetime(2000, 1, 1) + datetime.timedelta(minutes=10643385)
outputs
datetime.datetime(2020, 3, 27, 5, 45)
Python epoch time is in seconds, so we must first convert this to seconds by multiplying by 60.
Python epoch time starts on 1, Jan, 1970. Since netcdf starts on 2000-01-01, we must adjust by adding the amount of seconds from 1970 to 2000 (which happens to be 946684800).
Putting these together we get:
>>> import datetime
>>> epoch_time_value = 10643385
>>> _epoch_time_value = epoch_time_value * 60 + 946684800
>>> print(datetime.datetime.fromtimestamp(int(_epoch_time_value)).strftime('%Y-%m-%d %H:%M:%S'))
2020-03-26 22:45:00
Then, there may be some shift (possibly +/- 12 hours) based on timezone, so make sure the timezones in your calculations are synced when you do this!
I've got a pandas.Series object that might look like this:
import pandas as pd
myVar = pd.Series(["VLADIVOSTOK 690090", "MAHE", NaN, NaN, "VLADIVOSTOK 690090", "2000-07-01 00:00:00"])
myVar[5] is parsed as a datetime.datetime object when the data is read into Python via pandas. I'm assuming that converting this value to the number of days since epoch (36708) isn't difficult at all. I'm just new to Python and don't know how to do it. Thanks in advance!
I'm not sure where you're getting 36,708 days since the epoch (it's only been 16,644 days since January 1, 1970), but datetime.timedelta objects (used in date arithmetic) have a days attribute:
>>> import datetime
>>> (datetime.datetime.utcnow() - datetime.datetime(1970,1,1)).days
16644
myVar = pd.Series(["VLADIVOSTOK 690090", "MAHE", "NaN", "NaN", "VLADIVOSTOK 690090", "2000-07-01 00:00:00"])
myVar[5] = pd.to_datetime(myVar[5]) - pd.datetime(1970,1,1)
print(myVar)
0 VLADIVOSTOK 690090
1 MAHE
2 NaN
3 NaN
4 VLADIVOSTOK 690090
5 11139 days 00:00:00
dtype: object
You can convert this to seconds since epoch first, then divide it out by the amount of seconds in a day (86,400 seconds in a day). Please note the integer division here - will not return a float.
from datetime import datetime
now = datetime.now()
seconds = now.strftime("%s") # seconds since epoch
days = int(seconds) / 86400 # days since epoch
I added the import and now as an example of a datetime object I can play with.
For a Pandas Dataframe:
df_train["DaysSinceEpoch"] = [i.days for i in df_train["date"] - datetime.datetime(1970, 1, 1)]
Assuming that you want days since Unix Epoch of 1970-01-01 and you have a column of Pythonic datetime64[ns].
And see my other answer with the exact reverse.
I have a large data set with a variety of Date information in the following formats:
DAYS since Jan 1, 1900 - ex: 41213 - I believe these are from Excel http://www.kirix.com/stratablog/jd-edwards-date-conversions-cyyddd
YYDayofyear - ex 2012265
I am familiar with python's time module, strptime() method, and strftime () method. However, I am not sure what these date formats above are called on if there is a python module I can use to convert these unusual date formats.
Any idea how to get the %Y%M%D format from these unusual date formats without writing my own calculator?
Thanks.
You can try something like the following:
In [1]: import datetime
In [2]: s = '2012265'
In [3]: datetime.datetime.strptime(s, '%Y%j')
Out[3]: datetime.datetime(2012, 9, 21, 0, 0)
In [4]: d = '41213'
In [5]: datetime.date(1900, 1, 1) + datetime.timedelta(int(d))
Out[5]: datetime.date(2012, 11, 2)
The first one is the trickier one, but it uses the %j parameter to interpret the day of the year you provide (after a four-digit year, represented by %Y). The second one is simply the number of days since January 1, 1900.
This is the general conversion - not sure of your input format but hopefully this can be tweaked to suit it.
On the Excel integer to Python datetime bit:
Note that there are two Excel date systems (one 1-Jan-1900 based and another 1-Jan 1904 based); see https://support.microsoft.com/en-us/help/214330/differences-between-the-1900-and-the-1904-date-system-in-excel for more information.
Also note that the system is NOT zero-based. So, in the 1900 system, 1-Jan-1900 is day 1 (not day 0).
import datetime
EXCEL_DATE_SYSTEM_PC=1900
EXCEL_DATE_SYSTEM_MAC=1904
i = 42129 # Excel number for 5-May-2015
d = datetime.date(EXCEL_DATE_SYSTEM_PC, 1, 1) + datetime.timedelta(i-2)
Both of these formats seems pretty straightforward to work with. The first one, in fact, is just an integer, so why don't you just do something like this?
import datetime
def days_since_jan_1_1900_to_datetime(d):
return datetime.datetime(1900,1,1) + \
datetime.timedelta(days=d)
For the second one, the details depend on exactly how the format is defined (e.g. can you always expect 3 digits after the year even when the number of days is less than 100, or is it possible that there are 2 or 1 – and if so, is the year always 4 digits?) but once you've got that part down it can be done very similarly.
According to http://docs.python.org/2/library/datetime.html#strftime-and-strptime-behavior
, day of the year is "%j", whereas the first case can be solved by toordinal() and fromordinal(): date.fromordinal(date(1900, 1, 1).toordinal() + x)
I'd think timedelta.
import datetime
d = datetime.timedelta(days=41213)
start = datetime.datetime(year=1900, month=1, day=1)
the_date = start + d
For the second one, you can 2012265[:4] to get the year and use the same method.
edit: See the answer with %j for the second.
from datetime import datetime
df(['timeelapsed'])=(pd.to_datetime(df['timeelapsed'], format='%H:%M:%S') - datetime(1900, 1, 1)).dt.total_seconds()
I am creating a module in python, in which I am receiving the date in integer format like 20120213, which signifies the 13th of Feb, 2012. Now, I want to convert this integer formatted date into a python date object.
Also, if there is any means by which I can subtract/add the number of days in such integer formatted date to receive the date value in same format? like subtracting 30 days from 20120213 and receive answer as 20120114?
This question is already answered, but for the benefit of others looking at this question I'd like to add the following suggestion: Instead of doing the slicing yourself as suggested in the accepted answer, you might also use strptime() which is (IMHO) easier to read and perhaps the preferred way to do this conversion.
import datetime
s = "20120213"
s_datetime = datetime.datetime.strptime(s, '%Y%m%d')
I would suggest the following simple approach for conversion:
from datetime import datetime, timedelta
s = "20120213"
# you could also import date instead of datetime and use that.
date = datetime(year=int(s[0:4]), month=int(s[4:6]), day=int(s[6:8]))
For adding/subtracting an arbitary amount of days (seconds work too btw.), you could do the following:
date += timedelta(days=10)
date -= timedelta(days=5)
And convert back using:
s = date.strftime("%Y%m%d")
To convert the integer to a string safely, use:
s = "{0:-08d}".format(i)
This ensures that your string is eight charecters long and left-padded with zeroes, even if the year is smaller than 1000 (negative years could become funny though).
Further reference: datetime objects, timedelta objects
Here is what I believe answers the question (Python 3, with type hints):
from datetime import date
def int2date(argdate: int) -> date:
"""
If you have date as an integer, use this method to obtain a datetime.date object.
Parameters
----------
argdate : int
Date as a regular integer value (example: 20160618)
Returns
-------
dateandtime.date
A date object which corresponds to the given value `argdate`.
"""
year = int(argdate / 10000)
month = int((argdate % 10000) / 100)
day = int(argdate % 100)
return date(year, month, day)
print(int2date(20160618))
The code above produces the expected 2016-06-18.
import datetime
timestamp = datetime.datetime.fromtimestamp(1500000000)
print(timestamp.strftime('%Y-%m-%d %H:%M:%S'))
This will give the output:
2017-07-14 08:10:00