strftime() function showing different behaviour in system compiler and online compiler - python

Actually I am a newbie in python and there is the code that worries me a lot.
import time
from datetime import time, date, datetime
createdAt ='Wed Jan 12 11:45:28 +0000 2011' # createdAt value is read from a file
print 'CR= ',createdAt
struct_time = datetime.strptime(str(createdAt),'%a %b %d %H:%M:%S +0000 %Y').strftime('%s') # notice small s here
print "returned tuple: %s " % struct_time
I am getting an error like this in my compiler Python 2.7.10 Shell
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
asd = datetime.strptime(str(createdAt),'%a %b %d %H:%M:%S +0000 %Y').strftime('%s')
ValueError: Invalid format string
but in online compiler I am getting an output like this (online compiler at https://ideone.com/g0R2xw)
CR= Wed Jan 12 11:45:28 +0000 2011
returned tuple: 1294832728
I want my output to be this. Also if you can kindly tell me how this is calculated.
Thank You in advance...

From the documentation -
The full set of format codes supported varies across platforms, because Python calls the platform C library’s strftime() function, and platform variations are common. To see the full set of format codes supported on your platform, consult the strftime(3) documentation.
So the issue is that strftime() can behave differently based on the platform in which it is used.
Python directly does not support any %s (small s) , but seems like the linux system supports it , which could be why it is working in the online compiler, which inturn may be hosted on an linux environment. It worked in my linux envrionment as well.
If you want to convert a python datetime to seconds since epoch you should do it explicitly:
>>> import datetime
>>> (datetime.datetime.strptime(str(createdAt),'%a %b %d %H:%M:%S +0000 %Y') - datetime.datetime(1970,1,1)).total_seconds()
1294832728.0

Related

Python: date from plaintext (foreign language) weekday

I am looking to retrieve the next possible date for a weekday contained in a string. Complexity being that this weekday will be in foreign language (sv_SE).
In bash I can solve this using `dateround´:
startdate=$(dateround --from-locale=sv_SE -z CET today $startday)
Highly appreciate your guidance on how to solve this in Python.
Thank you very much!
Dateparser has support for quite a few languages. You could parse the weekday to a datetime object then determine the next possible date available.
-- Edit --
from dateparser import parse
parse('Onsdag').isoweekday() # 3
Now that you have the iso weekday, you can find the next possible date. You can refer to this to see how.
It seems locale aliases are platform specific and case sensitive. I've windows. So locale will be sv_SE.
You can use babel for date/time conversion and is much more comprehensive than native locale module.
Babel is an integrated collection of utilities that assist in internationalizing and localizing Python applications, with an emphasis on web-based applications.
Which can be installed as:
pip install Babel
Once installed, we can use format_date , format_datetime , format_time utilities to format one language date , time to other.
You can use these utilities to convert date/time data between English and Swedish.
>>>import datetime
>>>from babel.dates import format_date, format_datetime, format_time
#Here we get current date time in an datetime object
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2017, 10, 31, 9, 46, 32, 650000)
#We format datetime object to english using babel
>>> format_date(now, locale='en')
u'Oct 31, 2017'
#We format datetime object to sweedish using babel
>>> format_date(now, locale='sv_SE')
u'31 okt. 2017'
>>>

Robot Framework How to get different timezone and locale for different country?

In robot framework, the current supported keyword to get timezone is:
${month} Get Current Date result_format=%B%Y
which will return: July 2017
The question is how to get current date from other country and locale?
as example in Vietnam should return: Tháng Bảy 2017
and Thailand should return : กรกฎาคม พ.ศ. 2560
Unfortunately, python doesn't have good built-in support for formatting dates in locales other than the current one. You can temporarily switch locales, but that's not a great solution.
You can use the the Babel package to format the dates, though it doesn't provide precisely the same value you expect -- the case is slightly different.
For example, you could create a keyword that dates a month, year, and locale, and returns the formatted version.
First, create a python file named CustomKeywords.py with the following contents:
# CustomKeywords.py
import datetime
from babel.dates import format_date
class CustomKeywords:
def get_date_for_locale(self, locale, year, month=1, day=1):
d = datetime.date(int(year), int(month), int(day))
return format_date(d, "MMMM Y", locale=locale)
Next, import this library into your test case and then call get date for locale to get the date for a given locale:
*** Settings ***
Library CustomKeywords.py
*** Test Case ***
Vietnamese
${date}= get date for locale vi_VN 2017 7
Should be equal ${date} tháng bảy 2017
Thailand
${date}= get date for locale th_TH 2017 7
Should be equal ${date} กรกฎาคม 2017
In the Robot Framework Datetime library the concept of changing the TimeZone is not present. The Robot Framework Custom Timestamp functions rely on the underlying Python datatime.strptime function. This function uses the python Locale for it's formatting.
As this has now become a more general Python problem, I've searched SO and found this particular SO answer to fulfill the criteria to create a custom Python Keyword for Robot Framework that would allow changing the Locale and thus determine the output.

Python datetime strptime() and strftime(): how to preserve the timezone information

See the following code:
import datetime
import pytz
fmt = '%Y-%m-%d %H:%M:%S %Z'
d = datetime.datetime.now(pytz.timezone("America/New_York"))
d_string = d.strftime(fmt)
d2 = datetime.datetime.strptime(d_string, fmt)
print d_string
print d2.strftime(fmt)
the output is
2013-02-07 17:42:31 EST
2013-02-07 17:42:31
The timezone information simply got lost in the translation.
If I switch '%Z' to '%z', I get
ValueError: 'z' is a bad directive in format '%Y-%m-%d %H:%M:%S %z'
I know I can use python-dateutil, but I just found it bizzare that I can't achieve this simple feature in datetime and have to introduce more dependency?
Part of the problem here is that the strings usually used to represent timezones are not actually unique. "EST" only means "America/New_York" to people in North America. This is a limitation in the C time API, and the Python solution is… to add full tz features in some future version any day now, if anyone is willing to write the PEP.
You can format and parse a timezone as an offset, but that loses daylight savings/summer time information (e.g., you can't distinguish "America/Phoenix" from "America/Los_Angeles" in the summer). You can format a timezone as a 3-letter abbreviation, but you can't parse it back from that.
If you want something that's fuzzy and ambiguous but usually what you want, you need a third-party library like dateutil.
If you want something that's actually unambiguous, just append the actual tz name to the local datetime string yourself, and split it back off on the other end:
d = datetime.datetime.now(pytz.timezone("America/New_York"))
dtz_string = d.strftime(fmt) + ' ' + "America/New_York"
d_string, tz_string = dtz_string.rsplit(' ', 1)
d2 = datetime.datetime.strptime(d_string, fmt)
tz2 = pytz.timezone(tz_string)
print dtz_string
print d2.strftime(fmt) + ' ' + tz_string
Or… halfway between those two, you're already using the pytz library, which can parse (according to some arbitrary but well-defined disambiguation rules) formats like "EST". So, if you really want to, you can leave the %Z in on the formatting side, then pull it off and parse it with pytz.timezone() before passing the rest to strptime.
Unfortunately, strptime() can only handle the timezone configured by your OS, and then only as a time offset, really. From the documentation:
Support for the %Z directive is based on the values contained in tzname and whether daylight is true. Because of this, it is platform-specific except for recognizing UTC and GMT which are always known (and are considered to be non-daylight savings timezones).
strftime() doesn't officially support %z.
You are stuck with python-dateutil to support timezone parsing, I am afraid.
Here is my answer in Python 2.7
Print current time with timezone
from datetime import datetime
import tzlocal # pip install tzlocal
print datetime.now(tzlocal.get_localzone()).strftime("%Y-%m-%d %H:%M:%S %z")
Print current time with specific timezone
from datetime import datetime
import pytz # pip install pytz
print datetime.now(pytz.timezone('Asia/Taipei')).strftime("%Y-%m-%d %H:%M:%S %z")
It will print something like
2017-08-10 20:46:24 +0800
Try this:
import pytz
import datetime
fmt = '%Y-%m-%d %H:%M:%S %Z'
d = datetime.datetime.now(pytz.timezone("America/New_York"))
d_string = d.strftime(fmt)
d2 = pytz.timezone('America/New_York').localize(d.strptime(d_string,fmt), is_dst=None)
print(d_string)
print(d2.strftime(fmt))

How can I convert an RFC 822 timestamp into a human readable format in Python?

Does anyone know of a Python module that will convert an RFC 822 timestamp into a human readable format (like Twitter does) in Python?
I found parsedatetime, which seems to do the reverse.
In python, you can use rfc822 module. This module provides the parsedate method.
Attempts to parse a date according to the rules in RFC 2822.
However, this module is deprecated.
Deprecated since version 2.3: The email package should be used in preference to the rfc822 module. This module is present only to maintain backward compatibility, and has been removed in 3.0.
According to this comment, it's better to use the parsedate method from the email.utils module.
email.utils.parsedate(date)
EDIT:
Example code :
import email.utils
from time import mktime
from datetime import datetime
example_date = "Sat, 02 Mar 2011 15:00:00"
date_parsed = email.utils.parsedate(example_date)
dt = datetime.fromtimestamp(mktime(date_parsed))
today = datetime.today()
diff_date = today - dt # timedelta object
print "%s days, %s hours ago" \
% (diff_date.days, diff_date.seconds / 3600)
Output (for now) :
31 days, 2 hours ago
datetime.strptime will turn the times stamp into a datetime object which you can format with datetime.strftime
http://docs.python.org/library/datetime.html#strftime-strptime-behavior
See
http://docs.python.org/library/rfc822.html#rfc822.parsedate

Convert Chrome history date/time stamp to readable format

I originally posted this question looking for an answer with using python, got some good help, but have still not been able to find a solution. I have a script running on OS X 10.5 client machines that captures internet browsing history (required as part of my sys admin duties in a US public school). Firefox 3.x stores history in a sqlite db, and I have figured out how to get that info out using python/sqlite3. Firefox 3.x uses a conventional unixtimestamp to mark visits and that is not difficult to convert... Chrome also stores browser history in a sqlite db, but its timestamp is formatted as the number of microseconds since January, 1601. I'd like to figure this out using python, but as far as I know, the sqlite3 module doesn't support that UTC format. Is there another tool out there to convert Chrome timestamps to a human readable format?
Use the datetime module. For example, if the number of microseconds in questions is 10**16:
>>> datetime.datetime(1601, 1, 1) + datetime.timedelta(microseconds=1e16)
datetime.datetime(1917, 11, 21, 17, 46, 40)
>>> _.isoformat()
'1917-11-21T17:46:40'
this tells you it was just past a quarter to 6pm of November 21, 1917. You can format datetime objects in any way you want thanks to their strftime method, of course. If you also need to apply timezones (other than the UTC you start with), look at third-party module pytz.
Bash
$ date -ud #$[13315808702856828/10**6-11644473600] +"%F %T %Z"
2022-12-18 03:45:02 UTC
$ printf '%(%FT %T %z)T\n' $[13315808702856828/10**6-11644473600]
2022-12-17 T19:45:02 -0800
Perl
$ echo ".. 13315808702856828 .." |\
perl -MPOSIX -pe 's!\b(1\d{16})\b!strftime(q/%F/,gmtime($1/1e6-11644473600))!e'
.. 2022-12-17 ..

Categories