How do I convert an aware datetime to a POSIX timestamp? - python-2.7

I'd like to specify 12 PM on a particular date in the central timezone and adjust for daylight savings time (CDT). I'd then like to convert this to a POSIX timestamp.
The first thing I reached for is:
d = datetime.datetime(2017, 6, 27, 12, tzinfo=???)
But I don't have a concrete CDT class. pytz does however:
z = pytz.timezone('EST5EDT')
d = datetime.datetime(2017, 6, 27, 12, tzinfo=z)
But this does not work (pytz documentation says as much but I don't understand why the constructor cannot use the timezone information). If I use November (fall back) or June (spring forward) I get still get 12:00:00-05:00 as the time portion.
Even if this did work the method to convert to a POSIX timestamp assumes a naive datetime:
posix = time.mktime(d.timetuple())
This timestamp represents 12PM in my local time zone.
Then there is normalize() with code and examples that I find very difficult to follow:
au_dt = au_tz.normalize(utc_dt.astimezone(au_tz))
I also tried to subtract my aware time from an epoch defined at January 1, 1970 but that doesn't work unless the datetime gets the UTC offset correct (see my second point above).
Can anyone help me with a mental model of how this stuff works in general and a solution to this problem in particular?

This solution seems to work:
import pytz
import datetime
# Naive datetime (no timezone).
d = datetime.datetime(2017, 11, 27, 12)
cdt = pytz.timezone('US/Central')
# Give it a central time zone context.
d = cdt.localize(d)
# Determine the time in UTC.
d = d.astimezone(pytz.utc)
# Create a naive POSIX epoch.
epoch = datetime.datetime(1970, 1, 1)
# Give it context in the UTC time zone.
epoch = pytz.utc.localize(epoch)
# Number of seconds have elapsed since the epoch.
print (d - epoch).total_seconds()

Related

Get single digit time in python

I am using following code to get current time in python.
import datetime
now = datetime.datetime.now()
message_sent_time = now.strftime("%I:%M %p")
It returns time as
06:58 PM
However, I would like to get output as
6:58 PM
i.e. single digit time when time is before 10. How can I achieve it?
You can get a single-digit hour using %-I:
>>> message_sent_time = now.strftime("%-I:%M %p")
>>> print(message_sent_time)
7:07 PM
Full strftime formatting reference: http://strftime.org/

How to get Current Date in Ballerina

Is there a way to get the current date in ballerina?
As I was browsing through some code examples I came across the syntax to get the current time. Shown below is how to get the current date in Ballerina:
Note: first you have to import the time package given below for this to work.
import ballerina/time;
Then put the following lines of code:
time: Time currentTime = time:[currentTime][2]();
string customTimeString = currentTime.format("dd-MM-yyyy");
This will give the following output:
08-07-2018
This is work for ballerina 0.991 and 1.0 first you have to import the time package
Then it will give the current date if you want to get in a format it will included the code
import ballerina/time;
To get current time
time:Time time = time:currentTime();
string standardTimeString = time:toString(time);
io:println("Current system time in ISO format: ", standardTimeString);
To format the time
string|error customTimeString = time:format(time, "yyyy-MM-dd-E");
if (customTimeString is string) {
io:println("Current system time in custom format: ", customTimeString);
}
y -Years
M -months
d -date
E -day
h -hour
m -Minuit
s -seconds
For Swan Lake Update 3 they seem to have removed the time:currentTime() function.
It seems they have replaced it with time:utcNow().
According to the ballerina documentation,
"The time:Utc is the tuple representation of the UTC. The UTC represents the number of seconds from a specified epoch. Here, the epoch is the UNIX epoch of 1970-01-01T00:00:00Z."
So you can convert this above tuple representation to RFC 3339 timestamp by using,
time:Utc currTime = time:utcNow();
string date = time:utcToString(currTime);
io:println(date);
Then you will get a result like below,
2023-01-14T17:04:15.639510400Z
Using ballerina time library you can convert to other different representations as well.

Convert UTC timestamp to Simple binary encoded message

I am trying to convert UTC timestamp to simple binary encoded message.
Would like to achieve what is mentioned in example here.
Binary Encoding Example
The following timestamp:
UTC timestamp 14:17:22 Friday, October 4, 2024
is expressed in binary code (nanoseconds since Unix epoch) this way:
007420bf8838fb17 (8 bytes in nanoseconds since Unix epoch synced to a master clock to microsecond accuracy.
What I have done so far is,
import struct
from datetime import datetime
dt = datetime(2024, 10, 4, 14, 17, 22, 0)
timestamp = (dt - datetime(1970, 1, 1)).total_seconds() * 1000000000
utc_timestamp = struct.pack('d', timestamp)
Output I see on CLI is '\xf4\x02\x82\xa1E\xfb\xb7C' but, as per example in shared link, expected is 007420bf8838fb17
TL;DR: I think there's either an error in linked example, or the description of the representation is incorrect or incomplete.
import struct
from datetime import datetime, timedelta, timezone
utc_tz = timezone(timedelta(0))
t = datetime(2024, 10, 4, 14, 17, 22, 0, utc_tz)
nanos = int(t.timestamp()) * 1_000_000_000
print(hex(timestamp))
This gives the result of 0x17fb45a18202f400, not the quoted 0x17fb3888bf297400 (as presented, I think it's a little-endian byte string, so this value has the order of bytes reversed).
The quoted answer, converted to decimal seconds (dividing by 1_000_000_000) is 1728037042.0005898. That value obviously has a sub-second quantity, which the source datetime does NOT have.
Decoding the seconds component of the quoted answer:
import time
answer = 0x17fb3888bf297400
secs = int(answer / 1_000_000_000)
print(time.gmtime(secs))
gives:
time.struct_time(tm_year=2024, tm_mon=10, tm_mday=4, tm_hour=10, tm_min=17, tm_sec=22, tm_wday=4, tm_yday=278, tm_isdst=0)
which looks almost correct, save that the hour component is 4 hours earlier. So ... my guess is that this is actually a US/Eastern timestamp (not UTC), and contains a sub-second component of 5898ns, and the example is misleading.
If the schema you're using is encoding timestamps as a 64-bit number of nanoseconds since the Unix epoch (midnight 1 January 1970), then I think your example code has only one error: use format <q (or <Q) rather than d, and you'll get a little-endian 64-bit integer as required. You will also need to convert the timestamp to an integer to have struct.pack() accept it.

python - Difference between two unix timestamps

I have two timestamps in miliseconds and i want to compute the difference between the two in minutes:
d1 = 1502053449617
current_time_utc = int(round(time.time() * 1000))
The values for d1 are dynamically generated by a third party API and are in UTC . I am trying to get the difference between the current time in UTC and d1.
fmt = '%Y-%m-%d %H:%M:%S'
time1 = datetime.strptime(d1, fmt)
time2 = datetime.strptime(current_time_utc, fmt)
I want to be able to find the difference between the two (time1 - time2) . If i do the below , i get an error saying "string expected, long given"
print( time1-time2)
I want the difference between the two in minutes . Please help
You don't need to format the string, you just need to convert the timestamp directly, by first dividing it by 1000. Then its just a matter of printing out the differences (and calculating it in minutes):
from __future__ import division
import datetime
d1 = 1502053449617
converted_d1 = datetime.datetime.fromtimestamp(round(d1 / 1000))
current_time_utc = datetime.datetime.utcnow()
print((current_time_utc - converted_d1))
print((current_time_utc - converted_d1).total_seconds() / 60)
The above prints:
3 days, 5:08:14.087515
4628.234791916667
I had to calculate the difference between two unix timestamps - but in days, as follows:
create two unix timestamps:
import datetime
timestamp1 = datetime.datetime(2017, 12, 1).strftime('%s')
timestamp2 = datetime.datetime(2017, 11, 14).strftime('%s')
print(timestamp1)
print(timestamp2)
1512079200
1510610400
calculate the day difference:
print((float(timestamp1)-float(timestamp2))/(60*60*24))
output:
17.0

Bokeh glyph coordinates with x_axis_type 'datetime'

I am attempting to add a simple text string (glyph) to a Bokeh plot which uses x_axis_type='datetime'
My code (stripped to its essentials ) is as follows:
p = figure(plot_width=900, plot_height=380, x_axis_type='datetime')
dt = date(2003, 3, 15)
p.line(xvals, yvals)
txt = Text(
# x=some_formatting_function(dt),
x=1057005600000,
y=0.1,
text=["happy day!"],
text_align="left",
text_baseline="middle",
text_font_size="11pt",
text_font_style="italic",
)
p.add_glyph(txt)
show(p)
The x-axis range/values (ie dates) run from 2002 to 2006 and I'd like to add the text in, say, 2003. The x value I've shown in the code above (ie 1057005600000 -- which I've worked out by trial and error) drops the glyph in the right place.
But I cant work out how to use a datetime.date directly...
Is there a bokeh function (or a property of datetime.date) that will give me the value which the bokeh plot is expecting??
Many thanks.
N.B. I've tried using x = bokeh.properties.Date(dt) but this gives me:
ValueError: expected an element of either String,
Dict(String, Either(String, Float)) or Float, got <bokeh.properties.Date object
When the x_axis_type attr is set to 'datetime', Bokeh will plot things along the x-axis according to seconds-since-epoch. The easiest solution is to use datetime.datetime (not .date) and then cast your dt object to seconds-since-epoch using the timestamp() method (which will give the ~1.50e9 number you're getting) then use that for your x-coordinate.
$ from datetime import datetime
$ dt = datetime.now()
$ dt
> datetime.datetime(2015, 6, 17, 10, 41, 34, 617709)
$ dt.timestamp()
> 1434555694.617709
See the following SO question/answer for the python2 answer to my problem:
How can I convert a datetime object to milliseconds since epoch (unix time) in Python?
Thank you #Luke Canavan for pointing me in the right direction(!)