Pandas strftime with 24 hour format - python-3.x

QUESTION
How can I convert 24 hour time to 12 hour time, when the time provided is two characters long? For example: How to format 45 as 12:45 AM.
ATTEMPT
I can get most of the time conversions to format properly with the following:
df=df.assign(newtime=pd.to_datetime(df['Time Occurred'], format='%H%M').dt.strftime("%I:%M %p"))
df.head()
Date Reported Date Occurred Time Occurred newtime
9/13/2010 9/12/2010 45 4:05 AM
8/9/2010 8/9/2010 1515 3:15 PM
1/8/2010 1/7/2010 2005 8:05 PM
1/9/2010 1/6/2010 2100 9:00 PM
1/15/2010 1/15/2010 245 2:45 AM
In the above the values in newtime are properly formatted, except where in the input time is "45" - that time had the result 4:05 AM. Does anyone know how to create the proper output?

to_datetime
times = pd.to_datetime([
f'{h:02d}:{m:02d}:00' for h, m in zip(*df['Time Occurred'].astype(int).__divmod__(100))
])
df.assign(newtime=times.strftime('%I:%M %p'))
Time Occurred newtime
0 45 12:45 AM
1 1515 03:15 PM
2 2005 08:05 PM
3 2100 09:00 PM
4 245 02:45 AM

Related

moment.js give wrong time in diffent timezone

Epoch time for 2nd July 2018 , 11 PM. (IST)
> moment('2018-07-02T23:00:00.000').unix()
1530552600
Now When I convert from epoch to IST, It added 7 minute Extra.
> moment.unix(1530552600).tz("Asia/Kolkata").format("DD:MM:YYYY HH:MM z");
'02:07:2018 23:07 IST'
When converted to ET timezone , It gives 30 minute less from IST timezone. ET is 9.5 behind IST so it should have been "02:07:2018 01:30:00 EDT'
> moment.unix(1530552600).tz("America/New_York").format("DD:MM:YYYY HH:MM z");
'02:07:2018 13:07 EDT'
IST
your formatting string is wrong, you used MM (month) instead of mm (minutes)
try
moment.unix(1530552600).tz("Asia/Kolkata").format("DD:MM:YYYY HH:mm z");
for all other formats see the moment documentation

Convert incomplete 12h datetime-like strings into appropriate datetime type

I've got a pandas Series containing datetime-like strings with 12h format, but without the am/pm abbreviations. It covers an entire month of data :
40 01/01/2017 11:51:00
41 01/01/2017 11:51:05
42 01/01/2017 11:55:05
43 01/01/2017 11:55:10
44 01/01/2017 11:59:30
45 01/01/2017 11:59:35
46 02/01/2017 12:00:05
47 02/01/2017 12:00:10
48 02/01/2017 12:13:20
49 02/01/2017 12:13:25
50 02/01/2017 12:24:50
51 02/01/2017 12:24:55
52 02/01/2017 12:33:30
Name: TS, dtype: object
(318621,) # shape
My goal is to convert it to datetime format, so as to obtain the appropriate unix timestamps values, and make comparisions/arithmetics with other datetime data with, this time, 24h format. So I already tried this :
pd.to_datetime(df.TS, format = '%d/%m/%Y %I:%M:%S') # %I for 12h format
Which outputs me :
64 2017-01-02 00:46:50
65 2017-01-02 00:46:55
66 2017-01-02 01:01:00
67 2017-01-02 01:01:05
68 2017-01-02 01:05:00
But the am/pm informations are not taken into account. I know that, as a rule, the am/pm first have to be specified in the strings, then one can use dt.dt.strptime() or pd.to_datetime() to parse them with the %p indicator.
So I wanted to know if there's an other way to deal with this issue through datetime or pandas datetime modules ? Or, do I have to manualy add the abbreviations 'am/pm' before the parsing ?
You have data in 5 second intervals throughout multiple days. The desired end format is like this (with AM/PM column we need to add, because Pandas cannot possibly guess, since it looks at one value at a time):
31/12/2016 11:59:55 PM
01/01/2017 12:00:00 AM
01/01/2017 12:00:05 AM
01/01/2017 11:59:55 AM
01/01/2017 12:00:00 PM
01/01/2017 12:59:55 PM
01/01/2017 01:00:00 PM
01/01/2017 01:00:05 PM
01/01/2017 11:59:55 PM
02/01/2017 12:00:00 AM
First, we can parse the whole thing without AM/PM info, as you already showed:
ts = pd.to_datetime(df.TS, format = '%d/%m/%Y %I:%M:%S')
We have a small problem: 12:00:00 is parsed as noon, not midnight. Let's normalize that:
ts[ts.dt.hour == 12] -= pd.Timedelta(12, 'h')
Now we have times from 00:00:00 to 11:59:55, twice per day.
Next, note that the transitions are always at 00:00:00. We can easily detect these, as well as the first instance of each date:
twelve = ts.dt.time == datetime.time(0,0,0)
newdate = ts.dt.date.diff() > pd.Timedelta(0)
midnight = twelve & newdate
noon = twelve & ~newdate
Next, build an offset series, which should be easy to inspect for correctness:
offset = pd.Series(np.nan, ts.index, dtype='timedelta64[ns]')
offset[midnight] = pd.Timedelta(0)
offset[noon] = pd.Timedelta(12, 'h')
offset.fillna(method='ffill', inplace=True)
And finally:
ts += offset

Adding time to calendar date in Linux gives incorrect result

I am on Linux and I am trying to add a certain number of days, hours and minutes to a specified calendar date using the date tool:
For example:
$ date -d "2013-01-01 + 305 days 12 hours 30 minutes" +"%Y%m%d%0k%M%S"
20131102123000
Splitting the result up so it's easier for us to read:
2013-11-02 12:30:00
This appears to be working correctly. However, when I add 306 days instead of 305:
$ date -d "2013-01-01 + 306 days 12 hours 30 minutes" +"%Y%m%d%0k%M%S"
20131103113000
Split:
2013-11-03 11:30:00
Notice how the hour now shows 11 instead of 12! But I told it to add 12 hours... Let me increment the day one more time:
$ date -d "2013-01-01 + 307 days 12 hours 30 minutes" +"%Y%m%d%0k%M%S"
20131104123000
And split the result again:
2013-11-04 12:30:00
Now the hour goes back to what I expected. I have tested this using date versions 8.12 and 8.4, the same result happens on both. What am I doing wrong?
I was trying to add from a UTC date, but I did not specify this to the tool. This is the solution:
date --utc -d "2013-01-01 + 307 days 12 hours 30 minutes" +"%Y%m%d%0k%M%S"
Because UTC does not observe DST, there will be no shifts in the hour.

Finding out total worked hours and minutes formula

FROM TO FROM TO FROM TO
7:30 AM 2:00 PM 2:40 PM 2:40 PM 6:30 PM 12:00 AM
7:30 AM 2:00 PM 2:40 PM 2:40 PM 6:30 PM 12:00 AM
7:30 AM 2:00 PM 2:40 PM 2:40 PM 6:30 PM 12:00 AM
HOUR(H2-C2)& "h"&MINUTE(H2-C2)&"m")
HOUR(F2-E2)&"h")
Can you check what is the error in this formula:
(HOUR(H2-C2)& "h"&MINUTE(H2-C2)&"m")-(HOUR(F2-E2)&"h"& MINUTE(F2-E2)&"M")
I want the total hours worked by each person in this format: 12h48m
Don't you need the time between C2 and D2 added to the time between G2 and H2, that's what it looks like from your screenshot? You can also add in the difference between E2 and F2 if that's likely to be non-zero
You can use MOD function to handle times passing/on midnight, e.g.
=MOD(D2-C2,1)+MOD(H2-G2,1)+MOD(F2-E2,1)
Custom format result cell as [h]:mm and you'll get 12:00, I'm not sure why it would be 12:48. If you actually want it to display as 12h00m then use a custom format for the result cell of
[h]"h"mm"m"

Daily and Hourly Averages from (m/d/yyyy h:mm) timestamps in Excel

I have an Excel 2007 spreadsheet with date entries in this format m/d/yyyy h:mm (one cell). I would like find the hourly and daily average of all the columns of this spreadsheet and save each time aggregation to a new worksheet.
The data is recorded every ~10 minutes, but throughout the dates of data collection there was some time slips. Not every hour has the same number of rows. Also, the ending minute is either 0 or 6 depending on the time correction.
What would be a good way to approach this task within Excel 2007? It seems like this might be possible with a pivot table if I can create a formula that will select the correct range for the timestamps. Thanks.
For example, an date time entry in TIMESTAMP, 10/31/2012 0:06 which is in one cell.
TIMESTAMP Month Day Year Hour Min Rain_mm Rain_mm_2 AirTC AirTC_2 FuelM FuelM_2 VW ... there are ~16 variables (total) after the data time
10/31/2012 0:06 10 31 2012 0 06 0 0 26.11 26.08 2.545 6.4 0.049
10/31/2012 0:16 10 31 2012 0 16 0 0 25.98 25.97 2.624 6.6 0.049
10/31/2012 0:26 10 31 2012 0 26 0 0 24.32 23.33 2.543 6.5 0.048
10/31/2012 0:36 10 31 2012 0 36 0 0 24.32 23.33 2.543 6.5 0.048
10/31/2012 0:46 10 31 2012 0 46 0 0 24.32 23.33 2.543 6.5 0.048
10/31/2012 0:56 10 31 2012 0 56 0 0 25.87 25.87 2.753 7.3 0.049
10/31/2012 1:06 10 31 2012 0 06 0 0 25.74 25.74 2.879 8.1 0.051
## The above is just over one hour of collection on one day ##
...
## Different Day ### Notice Missing Time Stamp
11/30/2012 0:00 11 30 2012 0 06 0 0.1 26.12 26.18 2.535 6.4 0.049
11/30/2012 0:10 11 30 2012 0 16 0 0.1 25.90 25.77 2.424 6.6 0.049
11/30/2012 0:20 11 30 2012 0 26 0.1 0.2 24.12 24.43 2.542 6.4 0.046
11/30/2012 0:30 11 30 2012 0 36 0.1 0 24.22 22.32 2.543 6.5 0.048
11/30/2012 0:50 11 30 2012 0 56 0.1 0.2 26.77 25.87 2.743 6.3 0.049
11/30/2012 1:00 11 30 2012 0 06 0 0 24.34 24.77 2.459 5.1 0.050
## so forth on so on ##
After clarification of the requirement for daily averages edited to cover both daily and hourly averages:
Add a column (here B) for ‘H’ (ie hour) with =HOUR(A2) copied down.
(Note: Though formatted to show only m/d/y content of ColumnA is, in line with title, assumed to be all of mm/dd/yyyy hh:mm. Makes existing columns [with names jumbled] Month, Day, Year, Hour redundant).
Select data range.
Data, Subtotal, At each change in: TIMESTAMP, Use function: Average, Add subtotal to: check only columns G and to the right, OK.
Uncheck Replace current subtotals in Subtotal and apply At each change in: H, Use function: Average, and Add subtotal to: as before, OK.
Replace =SUBTOTAL(1, in Min column with =MIN( .
Delete ‘spare’ Grand Average row.
Reformat as required.
Hopefully this will be achieved and is what is required!:
Note midnight 'tonight' is counted as within first hour of tomorrow.
I had a similar need and worked it out this way:
Add a column for Date (assuming your dd/mm/yyyy hh:mm:ss data is in cell A2)
=DATE(YEAR(A2),MONTH(A2),DAY(A2))
Add a column for Year. If you have weeks from a single year, the year column can be neglected.
=YEAR(A2)
Add a column for Week Number
=WEEKNUM(A2)
Add 2 pivot tables, 1 for daily and 1 for weekly analysis.
Choose fields "Date" and the quantities you want. Put "Date" in the Rows section and sum/average of values in the Values section. You will get a date wise sum/average of the values you need.
In the weekly pivot table, do the same as above, just add "Year" and "Week no" in the Rows section instead of "Dates" as in above.
Hope this helps

Resources