Using a Unicode format for Python's `time.strftime()` - python

I am trying to call Python's time.strftime() function using a Unicode format string:
u'%d\u200f/%m\u200f/%Y %H:%M:%S'
(\u200f is the "Right-To-Left Mark" (RLM).)
However, I am getting an exception that the RLM character cannot be encoded into ascii:
UnicodeEncodeError: 'ascii' codec can't encode character u'\u200f' in position 2: ordinal not in range(128)
I have tried searching for an alternative but could not find a reasonable one. Is there an alternative to this function, or a way to make it work with Unicode characters?

Many standard library functions still don't support Unicode the way they should. You can use this workaround:
import time
my_format = u'%d\u200f/%m\u200f/%Y %H:%M:%S'
my_time = time.localtime()
time.strftime(my_format.encode('utf-8'), my_time).decode('utf-8')

You can format string through utf-8 encoding:
time.strftime(u'%d\u200f/%m\u200f/%Y %H:%M:%S'.encode('utf-8'), t).decode('utf-8')

You should read from a file as Unicode and then convert it to Date-time format.
from datetime import datetime
f = open(LogFilePath, 'r', encoding='utf-8')
# Read first line of log file and remove '\n' from end of it
Log_DateTime = f.readline()[:-1]
You can define Date-time format like this:
fmt = "%Y-%m-%d %H:%M:%S.%f"
But some programming language like C# doesn't support it easily, so you can change it to:
fmt = "%Y-%m-%d %H:%M:%S"
Or you can use like following way (to satisfy .%f):
Log_DateTime = Log_DateTime + '.000000'
If you have an unrecognized symbol (an Unicode symbol) then you should remove it too.
# Removing an unrecognized symbol at the first of line (first character)
Log_DateTime = Log_DateTime[1:] + '.000000'
At the end, you should convert string date-time to real Date-time format:
Log_DateTime = datetime.datetime.strptime(Log_DateTime, fmt)
Current_Datetime = datetime.datetime.now() # Default format is '%Y-%m-%d %H:%M:%S.%f'
# Calculate different between that two datetime and do suitable actions
Current_Log_Diff = (Current_Datetime - Log_DateTime).total_seconds()

Related

Error: time data "b'YYYY/MM/DD" does not match format '%Y/%m/%d' but it does

I'm trying to parse dates from a textfile, but executing the scripts throws incorrect data format, when the format is correct.
The file is a .txt file with the following structure
2018/02/15 05:00:13 - somestring - anotherstring
2018/02/15 05:00:14 - somestring - anotherstring
2018/02/15 05:00:15 - somestring - anotherstring
... etc
The script gets the file divided in lines, and each line is divided on fields, of which one field is a date and time. I divided the date and the time in two separate fields, the time gets converted ok so the problem is in the date.
This is what I get on execution:
ValueError: time data "b'2018/02/15" does not match format '%Y/%m/%d'
I noticed it prints the string with a "b" in front of it, which if I'm not mistaken it means it's a byte literal. I've tried using "decode("utf-8")" on it, but it throw's exception as "string" has no method decode.
#the file is in one long string as I get it from a 'cat' bash command via ssh
file = str(stdout.read()) #reads the cat into a long string
strings = file.split("\\n") #splits the string into lines
for string in strings:
fields = string.split(" - ")
if len(fields) >= 3:
#dates.append(datetime.strptime(campos[0],"%Y/%m/%d %H:%M:%S")) #Wrong format
datentime = fields[0].split()
dates.append(datetime.strptime(datentime[0],"%Y/%m/%d")) #Wrong format
print(datentime[1])
dates.append(datetime.strptime(datentime[1],"%H:%M:%S")) #WORKS
I can't figure out why that is happening to you with the code you gave so I can't offer a fix for that but I tried testing on it and this worked for me:
datetime.strptime(str(datentime[0])[2,:-1], "%Y/%m/%d")
It removes the B and ' from the string, if you still have problems with that, please post how you got that string, maybe there was some error on the way.
use try and except:
import datetime
def convertDate(d):
strptime = datetime.datetime.strptime
try:
return strptime(d, "%Y/%m/%d")
except TypeError:
return strptime(d.decode("utf-8"), "%Y/%m/%d")
print(convertDate(b'2018/02/15'))
print(convertDate('2018/02/15'))

Python adds extra to crypt result

I'm trying to create an API with token to communicate between an Raspberry Pi and a Webserver. Right now i'm tring to generate an Token with Python.
from Crypto.Cipher import AES
import base64
import os
import time
import datetime
import requests
BLOCK_SIZE = 32
BLOCK_SZ = 14
#!/usr/bin/python
salt = "123456789123" # Zorg dat de salt altijd even lang is! (12 Chars)
iv = "1234567891234567" # Zorg dat de salt altijd even lang is! (16 Chars)
currentDate = time.strftime("%d%m%Y")
currentTime = time.strftime("%H%M")
PADDING = '{'
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
secret = salt + currentTime
cipher=AES.new(key=secret,mode=AES.MODE_CBC,IV=iv)
encode = currentDate
encoded = EncodeAES(cipher, encode)
print (encoded)
The problem is that the output of the script an exta b' adds to every encoded string.. And on every end a '
C:\Python36-32>python.exe encrypt.py
b'Qge6lbC+SulFgTk/7TZ0TKHUP0SFS8G+nd5un4iv9iI='
C:\Python36-32>python.exe encrypt.py
b'DTcotcaU98QkRxCzRR01hh4yqqyC92u4oAuf0bSrQZQ='
Hopefully someone can explain what went wrong.
FIXED!
I was able to fix it to decode it to utf-8 format.
sendtoken = encoded.decode('utf-8')
You are running Python 3.6, which uses Unicode (UTF-8) for string literals. I expect that the EncodeAES() function returns an ASCII string, which Python is indicating is a bytestring rather than a Unicode string by prepending the b to the string literal it prints.
You could strip the b out of the output post-Python, or you could print(str(encoded)), which should give you the same characters, since ASCII is valid UTF-8.
EDIT:
What you need to do is decode the bytestring into UTF-8, as mentioned in the answer and in a comment above. I was wrong about str() doing the conversion for you, you need to call decode('UTF-8') on the bytestring you wish to print. That converts the string into the internal UTF-8 representation, which then prints correctly.

python the code strftime("%s") errors

THE python program is as follows, it errors:
File "C:\Python\PyCharmProject\FaceBookCrawl\group_download.py", line 31, in getFeed
params += "&since=" + SINCE.strftime("%s")
ValueError: Invalid format string
the program it seems SINCE.strftime("%s") is wrong, how to solve it?
SINCE = datetime.datetime.now() - datetime.timedelta(DAYS)
params = "?fields=permalink_url,from,story,type,message,link,created_time,updated_time,likes.limit(0).summary(total_count),comments.limit(0).summary(total_count)"
#Default paging limit
params += "&amp&limit=" + DEFAULT_LIMIT
#Time-based limit
params += "&since=" + SINCE.strftime("%s")
graph_url = GRAPH_URL_PREFIX + group + "/feed" + params
Actually, it should be capital S:
params += "&since=" + SINCE.strftime("%S")
^
ValueError: Invalid format string
You're using the wrong formatter i.e. it has to be upper case 'S' - here's datetime's strftime reference.
UnicodeEncodeError: 'locale' codec can't encode character '\uff33' in
position 1: Illegal byte sequence
the \uff33 is basically the the full width latin letter 'S' - the one you edited to get rid of previous ValueError.
Solution/way-outs:
1.Use raw string i.e. prefix your string with an 'r'
params = r"?fields=permalink_url,from,story,type,message,link,created_time,updated_time,likes.limit(0).summary(total_count),comments.limit(0).summary(total_count)"
2.If you're using str() to convert from unicode to encoded text / bytes - instead use .encode() to encode the string. A helpful SO thread.
For anybody coming here when using ("%s") to generate an Epoch timestamp. Note that the usage of strftime("%s") is platform dependent and doesnt work on windows while it works on Linux with you Local Timezone. You can just use timestamp():
int(datetime.datetime.utcnow().timestamp())
You can read more here Convert python datetime to epoch with strftime

How get a datetime string to suffix my filenames?

I need a function to generate datafile names with a suffix which must be the current date and time.
I want for the date Feb, 18 2014 15:02 something like this:
data_201402181502.txt
But this is that I get: data_2014218152.txt
My code...
import time
prefix_file = 'data'
tempus = time.localtime(time.time())
suffix = str(tempus.tm_year)+str(tempus.tm_mon)+str(tempus.tm_mday)+
str(tempus.tm_hour)+str(tempus.tm_min)
name_file = prefix_file + '_' + suffix + '.txt'
You can use time.strftime for this, which handles padding leading zeros e.g. on the month:
from time import strftime
name_file = "{0}_{1}.txt".format(prefix_file,
strftime("%Y%m%d%H%M"))
If you simply turn an integer to a string using str, it will not have the leading zero: str(2) == '2'. You can, however, specify this using the str.format syntax: "{0:02d}".format(2) == '02'.
Looks like you want
date.strftime(format)
The format string will allow you to control the output of strftime, try something like:
"%b-%d-%y"
From http://docs.python.org/2/library/datetime.html
Using str.format with datetime.datetime object:
>>> import datetime
>>> '{}_{:%Y%m%d%H%M}.txt'.format('filename', datetime.datetime.now())
'filename_201402182313.txt'

python strptime from UTC string to datetime regex re.sub

im using the following that works awesome for converting a UTC string to date times -- except when the milliseconds are LONGER than 6 digits. than it blows. urgh*&^*&
format = '%Y-%m-%dT%H:%M:%S'
if '.' in value:
format = format + '.%f'
if value.endswith('Z'):
format = format + 'Z'
return datetime.strptime(value, format)
here is the stacktrace
File "/usr/lib64/python2.6/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data '2013-07-19T13:02:53.8241899Z' does not match format '%Y-%m-%dT%H:%M:%S.%fZ'
whats a method to restrict the milliseconds to 6 digits in length. ive used using '{:%Y-%m-%dT%H:%M:%S.6%f}'.format( datetime ) but that helps nonce/
so trying re.sub( ) to limit the decimals (if any) following the '.'character in the provided string. but am not very regex savvy.
im using python 2.6.* on the machine.
Sounds like a job for dateutil.
$ pip install python-dateutil
$ python
>>> import dateutil.parser
>>> d = dateutil.parser.parse('2013-07-19T13:02:53.8241899Z')
>>> print d
2013-07-19 13:02:53.824189+00:00
You could use .partition() method to parse the string:
from datetime import datetime
sz = '2013-07-19T13:02:53.8241899Z' # utc time in rfc3339 format (without offset)
sz = sz.rstrip('Z') # remove ending 'Z' if present
timestr, _, digits = sz.partition('.')
utc_dt = datetime.strptime(timestr, '%Y-%m-%dT%H:%M:%S')
if digits:
microseconds = int(digits, 10) * 10**(6 - len(digits))
utc_dt = utc_dt.replace(microsecond=int(microseconds + .5))
If you want to use re.sub and don't mind truncating the microseconds:
import re
from datetime import datetime
sz = '2013-07-19T13:02:53.8241899Z'
if '.' in sz:
sz = re.sub(r'(\.\d{,6})\d*Z?$', r'\1Z', sz) # truncate to 6 digits +Z
else: # no fractions
sz = sz.rstrip('Z') + '.0Z'
utc_dt = datetime.strptime(sz, '%Y-%m-%dT%H:%M:%S.%fZ')
If you wanted to do it with re.sub, here's a short example of one way to do that.
import re
from datetime import datetime
value = '2013-07-19T13:02:53.8241899Z'
regex = r"(\d{6,}\d+)"
if re.search(regex, value):
repl = lambda x: x.group(0)[:6]
value = re.sub(pattern=regex, repl=repl, string=value)
format = '%Y-%m-%dT%H:%M:%S'
if '.' in value:
format = format + '.%f'
if value.endswith('Z'):
format = format + 'Z'
print datetime.strptime(value, format)

Categories