Python strftime – date without leading 0?

StackOverflow | strftime

When using Python strftime, is there a way to remove the first 0 of the date if it"s before the 10th, ie. so 01 is 1? Can"t find a %thingy for that?

Thanks!

Answer rating: 669

Actually I had the same problem and I realized that, if you add a hyphen between the % and the letter, you can remove the leading zero.

For example %Y/%-m/%-d.

This only works on Unix (Linux, OS X), not Windows (including Cygwin). On Windows, you would use #, e.g. %Y/%#m/%#d.

Answer rating: 203

We can do this sort of thing with the advent of the format method since python2.6:

>>> import datetime
>>> "{dt.year}/{dt.month}/{dt.day}".format(dt = datetime.datetime.now())
"2013/4/19"

Though perhaps beyond the scope of the original question, for more interesting formats, you can do stuff like:

>>> "{dt:%A} {dt:%B} {dt.day}, {dt.year}".format(dt=datetime.datetime.now())
"Wednesday December 3, 2014"

And as of python3.6, this can be expressed as an inline formatted string:

Python 3.6.0a2 (v3.6.0a2:378893423552, Jun 13 2016, 14:44:21) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> dt = datetime.datetime.now()
>>> f"{dt:%A} {dt:%B} {dt.day}, {dt.year}"
"Monday August 29, 2016"




Python strftime - date without leading 0?: StackOverflow Questions

Python strftime - date without leading 0?

When using Python strftime, is there a way to remove the first 0 of the date if it"s before the 10th, ie. so 01 is 1? Can"t find a %thingy for that?

Thanks!

Convert python datetime to epoch with strftime

I have a time in UTC from which I want the number of seconds since epoch.

I am using strftime to convert it to the number of seconds. Taking 1st April 2012 as an example.

>>>datetime.datetime(2012,04,01,0,0).strftime("%s")
"1333234800"

1st of April 2012 UTC from epoch is 1333238400 but this above returns 1333234800 which is different by 1 hour.

So it looks like that strftime is taking my system time into account and applies a timezone shift somewhere. I thought datetime was purely naive?

How can I get around that? If possible avoiding to import other libraries unless standard. (I have portability concerns).

How can I account for period (AM/PM) using strftime?

Specifically I have code that simplifies to this:

from datetime import datetime
date_string = "2009-11-29 03:17 PM"
format = "%Y-%m-%d %H:%M %p"
my_date = datetime.strptime(date_string, format)

# This prints "2009-11-29 03:17 AM"
print my_date.strftime(format)

What gives? Does Python just ignore the period specifier when parsing dates or am I doing something stupid?

Using %f with strftime() in Python to get microseconds

I"m trying to use strftime() to microsecond precision, which seems possible using %f (as stated here). However when I try the following code:

import time
import strftime from time

print strftime("%H:%M:%S.%f")

...I get the hour, the minutes and the seconds, but %f prints as %f, with no sign of the microseconds. I"m running Python 2.6.5 on Ubuntu, so it should be fine and %f should be supported (it"s supported for 2.6 and above, as far as I know.)

Answer #1

You can use strftime:

>>> from datetime import datetime
>>> datetime.today().strftime("%Y-%m-%d")
"2021-01-26"

Additionally, for anyone also looking for a zero-padded Hour, Minute, and Second at the end: (Comment by Gabriel Staples)

>>> datetime.today().strftime("%Y-%m-%d-%H:%M:%S")
"2021-01-26-16:50:03"

Answer #2

You can use dt.strftime if you need to convert datetime to other formats (but note that then dtype of column will be object (string)):

import pandas as pd

df = pd.DataFrame({"DOB": {0: "26/1/2016", 1: "26/1/2016"}})
print (df)
         DOB
0  26/1/2016 
1  26/1/2016

df["DOB"] = pd.to_datetime(df.DOB)
print (df)
         DOB
0 2016-01-26
1 2016-01-26

df["DOB1"] = df["DOB"].dt.strftime("%m/%d/%Y")
print (df)
         DOB        DOB1
0 2016-01-26  01/26/2016
1 2016-01-26  01/26/2016

Answer #3

date and datetime objects (and time as well) support a mini-language to specify output, and there are two ways to access it:

So your example could look like:

  • dt.strftime("The date is %b %d, %Y")
  • "The date is {:%b %d, %Y}".format(dt)
  • f"The date is {dt:%b %d, %Y}"

In all three cases the output is:

The date is Feb 23, 2012

For completeness" sake: you can also directly access the attributes of the object, but then you only get the numbers:

"The date is %s/%s/%s" % (dt.month, dt.day, dt.year)
# The date is 02/23/2012

The time taken to learn the mini-language is worth it.


For reference, here are the codes used in the mini-language:

  • %a Weekday as locale‚Äôs abbreviated name.
  • %A Weekday as locale‚Äôs full name.
  • %w Weekday as a decimal number, where 0 is Sunday and 6 is Saturday.
  • %d Day of the month as a zero-padded decimal number.
  • %b Month as locale‚Äôs abbreviated name.
  • %B Month as locale‚Äôs full name.
  • %m Month as a zero-padded decimal number. 01, ..., 12
  • %y Year without century as a zero-padded decimal number. 00, ..., 99
  • %Y Year with century as a decimal number. 1970, 1988, 2001, 2013
  • %H Hour (24-hour clock) as a zero-padded decimal number. 00, ..., 23
  • %I Hour (12-hour clock) as a zero-padded decimal number. 01, ..., 12
  • %p Locale‚Äôs equivalent of either AM or PM.
  • %M Minute as a zero-padded decimal number. 00, ..., 59
  • %S Second as a zero-padded decimal number. 00, ..., 59
  • %f Microsecond as a decimal number, zero-padded on the left. 000000, ..., 999999
  • %z UTC offset in the form +HHMM or -HHMM (empty if naive), +0000, -0400, +1030
  • %Z Time zone name (empty if naive), UTC, EST, CST
  • %j Day of the year as a zero-padded decimal number. 001, ..., 366
  • %U Week number of the year (Sunday is the first) as a zero padded decimal number.
  • %W Week number of the year (Monday is first) as a decimal number.
  • %c Locale‚Äôs appropriate date and time representation.
  • %x Locale‚Äôs appropriate date representation.
  • %X Locale‚Äôs appropriate time representation.
  • %% A literal "%" character.

Answer #4

The other alternate to avoid the "all or none" leading zero aspect above is to place a minus in front of the field type:

mydatetime.strftime("%-m/%d/%Y %-I:%M%p")

Then this: "4/10/2015 03:00AM"

Becomes: "4/10/2015 3:00AM"

You can optionally place a minus in front of the day if desired.

Edit: The minus feature derives from the GNU C library (“glibc”) as mentioned in the Linux strftime manpage under “Glibc notes”

Answer #5

Several answers here suggest using datetime.datetime.strptime to parse RFC 3339 or ISO 8601 datetimes with timezones, like the one exhibited in the question:

2008-09-03T20:56:35.450686Z

This is a bad idea.

Assuming that you want to support the full RFC 3339 format, including support for UTC offsets other than zero, then the code these answers suggest does not work. Indeed, it cannot work, because parsing RFC 3339 syntax using strptime is impossible. The format strings used by Python"s datetime module are incapable of describing RFC 3339 syntax.

The problem is UTC offsets. The RFC 3339 Internet Date/Time Format requires that every date-time includes a UTC offset, and that those offsets can either be Z (short for "Zulu time") or in +HH:MM or -HH:MM format, like +05:00 or -10:30.

Consequently, these are all valid RFC 3339 datetimes:

  • 2008-09-03T20:56:35.450686Z
  • 2008-09-03T20:56:35.450686+05:00
  • 2008-09-03T20:56:35.450686-10:30

Alas, the format strings used by strptime and strftime have no directive that corresponds to UTC offsets in RFC 3339 format. A complete list of the directives they support can be found at https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior, and the only UTC offset directive included in the list is %z:

%z

UTC offset in the form +HHMM or -HHMM (empty string if the the object is naive).

Example: (empty), +0000, -0400, +1030

This doesn"t match the format of an RFC 3339 offset, and indeed if we try to use %z in the format string and parse an RFC 3339 date, we"ll fail:

>>> from datetime import datetime
>>> datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%f%z")
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
    (data_string, format))
ValueError: time data "2008-09-03T20:56:35.450686Z" does not match format "%Y-%m-%dT%H:%M:%S.%f%z"
>>> datetime.strptime("2008-09-03T20:56:35.450686+05:00", "%Y-%m-%dT%H:%M:%S.%f%z")
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
    (data_string, format))
ValueError: time data "2008-09-03T20:56:35.450686+05:00" does not match format "%Y-%m-%dT%H:%M:%S.%f%z"

(Actually, the above is just what you"ll see in Python 3. In Python 2 we"ll fail for an even simpler reason, which is that strptime does not implement the %z directive at all in Python 2.)

The multiple answers here that recommend strptime all work around this by including a literal Z in their format string, which matches the Z from the question asker"s example datetime string (and discards it, producing a datetime object without a timezone):

>>> datetime.strptime("2008-09-03T20:56:35.450686Z", "%Y-%m-%dT%H:%M:%S.%fZ")
datetime.datetime(2008, 9, 3, 20, 56, 35, 450686)

Since this discards timezone information that was included in the original datetime string, it"s questionable whether we should regard even this result as correct. But more importantly, because this approach involves hard-coding a particular UTC offset into the format string, it will choke the moment it tries to parse any RFC 3339 datetime with a different UTC offset:

>>> datetime.strptime("2008-09-03T20:56:35.450686+05:00", "%Y-%m-%dT%H:%M:%S.%fZ")
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python3.4/_strptime.py", line 500, in _strptime_datetime
    tt, fraction = _strptime(data_string, format)
  File "/usr/lib/python3.4/_strptime.py", line 337, in _strptime
    (data_string, format))
ValueError: time data "2008-09-03T20:56:35.450686+05:00" does not match format "%Y-%m-%dT%H:%M:%S.%fZ"

Unless you"re certain that you only need to support RFC 3339 datetimes in Zulu time, and not ones with other timezone offsets, don"t use strptime. Use one of the many other approaches described in answers here instead.

Answer #6

The most voted answer suggests using fromtimestamp which is error prone since it uses the local timezone. To avoid issues a better approach is to use UTC:

datetime.datetime.utcfromtimestamp(posix_time).strftime("%Y-%m-%dT%H:%M:%SZ")

Where posix_time is the Posix epoch time you want to convert

Answer #7

The T doesn"t really stand for anything. It is just the separator that the ISO 8601 combined date-time format requires. You can read it as an abbreviation for Time.

The Z stands for the Zero timezone, as it is offset by 0 from the Coordinated Universal Time (UTC).

Both characters are just static letters in the format, which is why they are not documented by the datetime.strftime() method. You could have used Q or M or Monty Python and the method would have returned them unchanged as well; the method only looks for patterns starting with % to replace those with information from the datetime object.

Answer #8

You can get the week number directly from datetime as string.

>>> import datetime
>>> datetime.date(2010, 6, 16).strftime("%V")
"24"

Also you can get different "types" of the week number of the year changing the strftime parameter for:

%U - Week number of the year (Sunday as the first day of the week) as a zero padded decimal number. All days in a new year preceding the first Sunday are considered to be in week 0. Examples: 00, 01, …, 53

%W - Week number of the year (Monday as the first day of the week) as a decimal number. All days in a new year preceding the first Monday are considered to be in week 0. Examples: 00, 01, …, 53

[...]

(Added in Python 3.6, backported to some distribution"s Python 2.7"s) Several additional directives not required by the C89 standard are included for convenience. These parameters all correspond to ISO 8601 date values. These may not be available on all platforms when used with the strftime() method.

[...]

%V - ISO 8601 week as a decimal number with Monday as the first day of the week. Week 01 is the week containing Jan 4. Examples: 01, 02, …, 53

from: datetime — Basic date and time types — Python 3.7.3 documentation

I"ve found out about it from here. It worked for me in Python 2.7.6

Answer #9

If you"d like to have the date in English:

>>> from datetime import datetime
>>> datetime.today().strftime("%A")
"Wednesday"

Read more: https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior

Answer #10

You can use BackgroundScheduler() from APScheduler package (v3.5.3):

import time
import atexit

from apscheduler.schedulers.background import BackgroundScheduler


def print_date_time():
    print(time.strftime("%A, %d. %B %Y %I:%M:%S %p"))


scheduler = BackgroundScheduler()
scheduler.add_job(func=print_date_time, trigger="interval", seconds=60)
scheduler.start()

# Shut down the scheduler when exiting the app
atexit.register(lambda: scheduler.shutdown())

Note that two of these schedulers will be launched when Flask is in debug mode. For more information, check out this question.

Get Solution for free from DataCamp guru