UTC timestamp in python getting converted local - python

I am facing a very strange problem. I have UTC timestamp of one of the days of the month, and I need to find UTC timestamp of beginning of the month and end of month.
For example, if timestamp = 1435791600 for 07 Jan 2015 11 PM
I need timestamp one 01 Jan 2015 12 AM and 31 Jan 11:59 PM.
Issue is when I use datetime to calculate first and last day of the month, and then try to retrieve timestamps from new values, the timestamps are being returned in local time instead.
This is my code:
gb_timestamp = 1441065600000
print '------'
timestamp = datetime.datetime.utcfromtimestamp(gb_timestamp/1000.0)
print timestamp
print int(timestamp.strftime("%s")) * 1000
tsMonthStart = timestamp.replace(day=1).replace(hour=0).replace(minute=0).replace(second=0).replace(microsecond=0)
tsMonthEnd = timestamp.replace(hour=23).replace(minute=59).replace(second=59).replace(microsecond=999999)
mlist = [1,3,5,7,8,10,12]
if tsMonthEnd.month in mlist:
tsMonthEnd = tsMonthEnd.replace(day=31)
elif (tsMonthEnd.month == 2) and (tsMonthEnd.year%4 !=0):
tsMonthEnd = tsMonthEnd.replace(day=28)
elif (tsMonthEnd.month == 2) and (tsMonthEnd.year%4 ==0):
tsMonthEnd = tsMonthEnd.replace(day=29)
else:
tsMonthEnd = tsMonthEnd.replace(day=30)
print tsMonthStart
print tsMonthEnd
The very first print statement changes time to 1441080000000. Output:
----------------
1441080000000
Can someone please help. How should I resolve this. Thanks in advance.

That's not how you convert datetimes back to unix timestamps. Use something like this:
def datetime_to_timestamp(dt):
return (dt - datetime.datetime(1970, 1, 1)).total_seconds()
The answer here explains why strftime('%s') isn't valid for datetime objects.

Related

How to search a string for the first and second occurance of military time in python

So I'm doing some scraping in my django application.
The thing that I get when scraping contains a date element which looks something like this
7 april 2022 19:00 - 8 april 04:00 utc+02
I have already figured out how to pull the start day and both of the months, I am however having some trouble pulling the military times as well as the second day.
I'm thinking that I have to use the % operator in some way when searching for the military time but couldn't find much online and its been a while since I used python.
For the pulling of the second day I tried to do the same thing as I did when taking the first one the problem is however that i end up pulling the "02" from the "utc+02".
Thanks for any help I can get!
time = temp[0] # the content of scraping
emp_str = ""
f_digit = False
for d in time: # finds the first digit(s) aka the day
if d.isdigit():
emp_str = emp_str+d
f_digit = True
elif f_digit:
break
s_day = emp_str
emp_ar = []
s_month = ""
e_month = ""
for m in MONTHS: # this finds the months in the string and adds their index for comparing MONTHS contains the months aka apr jun jul and so on
index = time.find(m)
if index != -1:
emp_ar.append(m)
emp_ar.append(index)
if len(emp_ar) > 2:
print("happened")
# checks which index is bigger aka which one is mentioned first
if int(emp_ar[1]) < int(emp_ar[3]):
s_month = emp_ar[0]
e_month = emp_ar[2]
else:
s_month = emp_ar[2]
e_month = emp_ar[0]
elif len(emp_ar) > 0:
s_month = emp_ar[0]
e_month = emp_ar[0]
# puts the month in s/e month for start/end
You can use the datetime.datetime.strptime() method.
In the comments the format seems to have changed but going off the original format your code would have to look like this:
from datetime import datetime
s = '7 april 2022 19:00 - 8 april 04:00 utc+02'
s = s.split('-')
startdate = datetime.strptime(s[0].strip(), '%d %B %Y %H:%M')
enddate = datetime.strptime(s[1].strip()+'00', '%d %B %H:%M utc%z')
startdate = startdate.replace(tzinfo=enddate.tzinfo)
enddate = enddate.replace(year=startdate.year)
Edited to transfer the start year to the end year

How to print a date with dashes?

I'm quite lost and I'm in need of trying to format some code so it ends up having dashes in the date. I can get 3, 12, 28 but I can't get 3-12-28. I am a super new beginner so I'm quite lost at the moment.
year = 3
month = 12
day = 28
print(date)
Try
print("{0}-{1}-{2}".format(year,month,day))
You could use datetime to format the result
import datetime
year = 3
month = 12
day = 28
dt = (datetime.date(year, month, day))
print(dt)
the result will be 0003-12-28
if you want more examples of datetime you could take a look at https://docs.python.org/2/library/datetime.html#
As you say you are new to python you can concatenate the strings together.
year = 3
month = 12
day = 28
date = year + "-" + month + "-" + day
print(date)
Alternatively you can use format to set the variables in your required format.
print(f"{year}-{month}-{day}")
Another method is to use datetime if you are using todays date
import datetime
today = datetime.date.today()
print(today)

Split and Format Date Range

I am working on parsing a date range from an email in zapier. Here is what comes in: Dec 4 - Jan 4, 2020 From this I need to separate the start and end date to something like 12/04/2019 and 01/04/2020 accounting for the fact that some dates will start in the prior year as in the example above and some will be in the same year for example Mar 4 - Mar 22, 2020. It seems the code to use in zapier is python. I have looked at examples for panda
import pandas as pd
date_series = pd.date_range(start='Mar 4' -, end='Mar 7, 2020')
print(date)
But keep getting errors.
Any suggestions would be much appreciated thanks
This is one way to do it:
def parse_email_range(date_string):
dates = date_string.split(' - ')
month_1 = pd.to_datetime(dates[0], format='%b %d').month
month_2 = pd.to_datetime(dates[1]).month
day_1 = pd.to_datetime(dates[0], format='%b %d').day
day_2 = pd.to_datetime(dates[1]).day
year_2 = pd.to_datetime(dates[1]).year
year_1 = year_2 if (month_1 < month_2) or (month_1 == month_2 and day_1 < day_2) else year_2 - 1
return '{}-{}-{}'.format(year_1, month_1, day_1), '{}-{}-{}'.format(year_2, month_2, day_2)
parse_email_range('Dec 4 - Jan 4, 2020')
## ('2019-12-4', '2020-1-4')
Split the two dates and record them into a single variable:
raw_dates = 'Dec 4 - Jan 4, 2020'.split(" - ")
dateutil package is capable of parsing most dates:
from dateutil.parser import parse
Parse and separate start and end date from the raw dates:
start_date, end_date = (parse(date) for date in raw_dates)
strftime is the method that could be used to format dates.
Store desired format in a variable (please note I have used day first format):
date_format = '%d/%m/%Y'
Convert the end date into the desired format:
print(end_date.strftime(date_format))
'04/01/2020'
Convert start date:
dateutil's relativedelta function will help us to subtract one year from the start date:
from dateutil.relativedelta import relativedelta
adjusted_start_date = start_date - relativedelta(years=1)
print(adjusted_start_date.strftime(date_format))
'04/12/2019'

Making a .txt file calendar in Python 3.2 WITHOUT using .calendar

I'm trying to write a program that will give me a nice .txt file displaying this year's calendar, however, I don't want to use the calendar function, but datetime.
I want it to have the following format (I want to have the first 3 letter of every day of the week next to it):
Tue Jan 01
Wed Jan 02
all the way to
Tue Dec 31
(basically 365 lines altogether with 10 characters in every line, and every line ends in a newline "\n").
This is what I have gathered going from various stackflow questions, tutorials and modules. So far no success.
import datetime
from datetime import date
textfile = file('new_file.txt','wt')
your_date.isoformat()
your_date.strftime("%A %d. %B %Y")
My main issue is that I am unfamiliar with how I get python to give me a range of dates (here being the year 2013, but it could also be just any increment in time such as June 2011 to December 2014) and of course to print the day of the week next to it. This way it could be adapted to any time period you might need this small calendar for. I was thinking maybe assigning every day's number (1 being Monday, 2 being Tuesday is the pattern if I'm correct) the first 3 letters of a day in the week so it's all neat and of the same length.
Here's one way to do the looping:
inc = datetime.timedelta(days=1)
curr = datetime.date(2013, 1, 1)
end = datetime.date(2014, 1, 1)
while curr < end:
# print out the date and whatnot
curr += inc
#!/usr/bin/env python3
import sys
from datetime import date, timedelta
def gen_calendar(year=None):
if year is None:
year = date.today().year
current = date(year, 1, 1)
delta = timedelta(days=1)
while current.year == year:
yield current.strftime('%a %b %d')
current += delta
if __name__ == '__main__':
year = None
if len(sys.argv) > 1:
year = int(sys.argv[1])
for str_date in gen_calendar(year):
print(str_date)
this will print to stdout so you can redirect it to a file from the console, which is the usual but if you want to write to the file directly from the script replace the last two lines with this:
with open('calendar.txt', 'w') as f:
for str_date in gen_calendar(year):
print(str_date, file=f)

nth weekday calculation in Python - whats wrong with this code?

I'm trying to calculate the nth weekday for a given date. For example, I should be able to calculate the 3rd wednesday in the month for a given date.
I have written 2 versions of a function that is supposed to do that:
from datetime import datetime, timedelta
### version 1
def nth_weekday(the_date, nth_week, week_day):
temp = the_date.replace(day=1)
adj = (nth_week-1)*7 + temp.weekday()-week_day
return temp + timedelta(days=adj)
### version 2
def nth_weekday(the_date, nth_week, week_day):
temp = the_date.replace(day=1)
adj = temp.weekday()-week_day
temp += timedelta(days=adj)
temp += timedelta(weeks=nth_week)
return temp
Console output
# Calculate the 3rd Friday for the date 2011-08-09
x=nth_weekday(datetime(year=2011,month=8,day=9),3,4)
print 'output:',x.strftime('%d%b%y')
# output: 11Aug11 (Expected: '19Aug11')
The logic in both functions is obviously wrong, but I can't seem to locate the bug - can anyone spot what is wrong with the code - and how do I fix it to return the correct value?
Your problem is here:
adj = temp.weekday()-week_day
First of all, you are subtracting things the wrong way: you need to subtract the actual day from the desired one, not the other way around.
Second, you need to ensure that the result of the subtraction is not negative - it should be put in the range 0-6 using % 7.
The result:
adj = (week_day - temp.weekday()) % 7
In addition, in your second version, you need to add nth_week-1 weeks like you do in your first version.
Complete example:
def nth_weekday(the_date, nth_week, week_day):
temp = the_date.replace(day=1)
adj = (week_day - temp.weekday()) % 7
temp += timedelta(days=adj)
temp += timedelta(weeks=nth_week-1)
return temp
>>> nth_weekday(datetime(2011,8,9), 3, 4)
datetime.datetime(2011, 8, 19, 0, 0)
one-liner
You can find the nth weekday with a one liner that uses calendar from the standard library.
import calendar
calendar.Calendar(x).monthdatescalendar(year, month)[n][0]
where:
x : the integer representing your weekday (0 is Monday)
n : the 'nth' part of your question
year, month : the integers year and month
This will return a datetime.date object.
broken down
It can be broken down this way:
calendar.Calendar(x)
creates a calendar object with weekdays starting on your required weekday.
.monthdatescalendar(year, month)
returns all the calendar days of that month.
[n][0]
returns the 0 indexed value of the nth week (the first day of that week, which starts on the xth day).
why it works
The reason for starting the week on your required weekday is that by default 0 (Monday) will be used as the first day of the week and if the month starts on a Wednesday, calendar will consider the first week to start on the first occurrence of Monday (ie. week 2) and you'll be a week behind.
example
If you were to need the third Saturday of September 2013 (that month's US stock option expiry day), you would use the following:
calendar.Calendar(5).monthdatescalendar(2013,9)[3][0]
The problem with the one-liner with the most votes is it doesn't work.
It can however be used as a basis for refinement:
You see this is what you get:
c = calendar.Calendar(calendar.SUNDAY).monthdatescalendar(2018, 7)
for c2 in c:
print(c2[0])
2018-07-01
2018-07-08
2018-07-15
2018-07-22
2018-07-29
c = calendar.Calendar(calendar.SUNDAY).monthdatescalendar(2018, 8)
for c2 in c:
print(c2[0])
2018-07-29
2018-08-05
2018-08-12
2018-08-19
2018-08-26
If you think about it it's trying to organise the calendars into nested lists to print a weeks worth of dates at a time. So stragglers from other months come into play. By using a new list of valid days that fall in the month - this does the trick.
Answer with appended list
import calendar
import datetime
def get_nth_DOW_for_YY_MM(dow, yy, mm, nth) -> datetime.date:
#dow - Python Cal - 6 Sun 0 Mon ... 5 Sat
#nth is 1 based... -1. is ok for last.
i = -1 if nth == -1 or nth == 5 else nth -1
valid_days = []
for d in calendar.Calendar(dow).monthdatescalendar(yy, mm):
if d[0].month == mm:
valid_days.append(d[0])
return valid_days[i]
So here's how it could be called:
firstSundayInJuly2018 = get_nth_DOW_for_YY_MM(calendar.SUNDAY, 2018, 7, 1)
firstSundayInAugust2018 = get_nth_DOW_for_YY_MM(calendar.SUNDAY, 2018, 8, 1)
print(firstSundayInJuly2018)
print(firstSundayInAugust2018)
And here is the output:
2018-07-01
2018-08-05
get_nth_DOW_for_YY_MM() can be refactored using lambda expressions like so:
Answer with lambda expression refactoring
import calendar
import datetime
def get_nth_DOW_for_YY_MM(dow, yy, mm, nth) -> datetime.date:
#dow - Python Cal - 6 Sun 0 Mon ... 5 Sat
#nth is 1 based... -1. is ok for last.
i = -1 if nth == -1 or nth == 5 else nth -1
return list(filter(lambda x: x.month == mm, \
list(map(lambda x: x[0], \
calendar.Calendar(dow).monthdatescalendar(yy, mm) \
)) \
))[i]
The one-liner answer does not seem to work if the target day falls on the first of the month. For instance, if you want the 2nd Friday of every month, then the one-liner approach
calendar.Calendar(4).monthdatescalendar(year, month)[2][0]
for March 2013 will return March 15th 2013 when it should be March 8th 2013. Perhaps add in a check like
if date(year, month, 1).weekday() == x:
delivery_date.append(calendar.Calendar(x).monthdatescalendar(year, month)[n-1][0])
else:
delivery_date.append(calendar.Calendar(x).monthdatescalendar(year, month)[n][0])
Alternatively this will work for Python 2, returns the occurance of weekday in the said month, i.e if 16 June 2018 is the input, then returns the occurance of the day on 16th June 2018
You may substitute the month/year/date integers to anything you might want - right now it's getting the input / date from the system via datetime
Omit out print statements or use pass where they're not needed
import calendar
import datetime
import pprint
month_number = int(datetime.datetime.now().strftime('%m'))
year_number = int(datetime.datetime.now().strftime('%Y'))
date_number = int(datetime.datetime.now().strftime('%d'))
day_ofweek = str(datetime.datetime.now().strftime('%A'))
def weekday_occurance():
print "\nFinding current date here\n"
for week in xrange(5):
try:
calendar.monthcalendar(year_number, month_number)[week].index(date_number)
occurance = week + 1
print "Date %s of month %s and year %s is %s #%s in this month." % (date_number,month_number,year_number,day_ofweek,occurance)
return occurance
break
except ValueError as e:
print "The date specified is %s which is week %s" % (e,week)
myocc = weekday_occurance()
print myocc
A little tweak would make the one-liner work correctly:
import calendar
calendar.Calendar((weekday+1)%7).monthdatescalendar(year, month)[n_th][-1]
Here n_th should be interpreted as c-style, e.g. 0 is the first index.
Example: to find 1st Sunday in July 2018 one could type:
>>> calendar.Calendar(0).monthdatescalendar(2018, 7)[0][-1]
datetime.date(2018, 7, 1)
People here seem to like one-liner, I will propose below.
import calendar
[cal[0] for cal in calendar.Calendar(x).monthdatescalendar(year, month) if cal[0].month == month][n]
The relativedelta module that's an extension from the Python dateutil package (pip install python-dateutil) does exactly what you want:
from dateutil import relativedelta
import datetime
def nth_weekday(the_date, nth_week, week_day):
return the_date.replace(day=1) + relativedelta.relativedelta(
weekday=week_day(nth_week)
)
print(nth_weekday(datetime.date.today(), 3, relativedelta.FR))
The key part here evaluates to weekday=relativedelta.FR(3): the third Friday of the month. Here are the relevant part of the docs for the weekday parameter,
weekday:
One of the weekday instances (MO, TU, etc) available in the
relativedelta module. These instances may receive a parameter N,
specifying the Nth weekday, which could be positive or negative
(like MO(+1) or MO(-2)).

Categories