Increment times if date has changed? - python

I have a list of strings, and one of them looks like this:
'Thu Jun 18 19:58:02 2015
...many lines of data...
txup: 19:59:47 txdown: 20:05:22
rxup: 21:43:17 rxdown: 22:13:01'
But another may look like this:
'Fri Jun 19 23:12:12 2015
...many lines of data...
txup: 23:39:47 txdown: 23:57:22
rxup: 00:01:17 rxdown: 01:13:01'
As you can see, in some cases a time might cross midnight. When that happens, using the above string as an example, the date associated with that time would now be Jun 20 instead of Jun 19.
I need to write a code that compares the 'rxup' time with the date/time at the start of the string and recognizes if and when it increases by a day because it passed midnight (all relative to the date/time at the beginning).
If it hasn't crossed midnight and is thus the same day, then I'm done. But if it has crossed midnight, I need to take the difference between that time and the time at the beginning probably as a timedelta object, and add that increment onto a copy of the time at the beginning. How would I do this?

If the times grow monotonously you can simply compare them in lexicographic order. '00:01:17' is obviously less than '23:39:47', so each time next timestamp is less than the current one, you increment the date.

Assuming that rxup always appears after txdown, but less than 24 hours later, you can compare it like below:
# txdown, rxup - datetimes with respective times, date part doesn't matters
# associated_date - datetime associated with string
if rxup.time() < txdown.time():
associated_date += datetime.timedelta(days=1)

Related

What is the format for UNIX timestamp of '253402128000000'?

I'm trying to convert a whole column of timestamp values in UNIX format but I get some values that doesn't look like a normal timestamp format: 253402128000000
For what I know, a timestamp should look like: 1495245009655
I've tried in miliseconds, nanoseconds and other configurations for Pandas to_datetime but I haven't been able to find a solution that can convert the format.
EDIT
My data looks like below and the ValidEndDateTime seems way off.
"ValidStartDateTime": "/Date(1495245009655)/",
"ValidEndDateTime": "/Date(253402128000000)/",
SOLUTION
I've accepted the answer below because I can see the date is a "never-end" date as all the values in my dataset that can't be converted is set to the same value: 253402128000000
Thank you for the answers!
From a comment of yours:
The data I get looks like this: "ValidStartDateTime": "/Date(1495245009655)/", "ValidEndDateTime": "/Date(253402128000000)/",
The numbers appear to be UNIX timestamps in milliseconds and the big "End" one seems to mean "never end", note the special date:
1495245009655 = Sat May 20 2017 01:50:09
253402128000000 = Thu Dec 30 9999 00:00:00
Converted with https://currentmillis.com/
I think it was divided by 1,000,000 becoming 253402128 and calculated.
Which means approximately 44 years ago.
Format: Microseconds (1/1,000,000 second)
GMT: Wed Jan 11 1978 21:28:48 GMT+0000
I used this website as reference: https://www.unixtimestamp.com/
Use pd.to_datetime:
>>> pd.to_datetime(1495245009655, unit='ms')
Timestamp('2017-05-20 01:50:09.655000')
>>> pd.to_datetime(253402128000000 / 100, unit='ms')
Timestamp('2050-04-19 22:48:00')

Python - Check every other week using if statement

I have the following if statement:
if date.weekday() != 0:
How can I change this if statement to check every other Monday (one day every other week)?
Thanks in advance for your help!
You post doesn't mention what language you're using. That would be useful to know!
At any rate, a function like weekday probably returns a number from 0-6, which isn't going to give you enough info.
Most languages have a function that turns a date into a millisecond value, typically milliseconds since 1970-01-01 00:00 UTC.
If you take such a value and divide it by 86400000 (number of milliseconds in a day), you get a day number. Day 0 (January 1, 1970) happens to be a Thursday.
In JavaScript, this day number can be obtained from a Date object like this:
let dayNum = Math.floor(someDate.getTime() / 86400000)
From this, dayNum % 7 gives you a number from 0-6 for Thursday through Wednesday. You can add an offset to change what 0 means. (dayNum + 4) % 7 produces 0-6 for Sunday through Saturday.
You want a 14-day cycle for every other week, so dayNum % 14 is what you need, and you then just have to decide which value from 0 to 13 represents your target dates.
Take any sample date that is one of your desired dates, compute the remainder value you get for that date, and then test for that value to be able to match any qualifying date.
Two caveats:
For dates before 1970, the % operator might produces negative numbers. Python is one of the few languages that doesn't do this.
The timezone offset from UTC might be important to your task. And if that's important, Daylight Saving Time changes and/or historical changes in UTC offset can complicate matters.
Python update:
Let's say this coming Monday (July 5, 2021) is one of the every-other-week days that you want. This:
date(2021, 7, 5).toordinal() % 14
...produces a value of 8. Every other Monday before or after will also be 8. The toordinal() method goes straight to a day number, without having to fuss with milliseconds, 86400000, or having to worry about timezone offsets.

Probabilistic generation of datetimes according to the period of the day

I intend to generate datetimes of an entire day, with a 5 minute difference between each one, but I would like to do this probabilistically. For example:
on datetimes between 00:00 and 06:00, there would be a 100%
probability of generating a datetime; this way, all datetimes would
be generated (00:00, 00:05, 00:10 ...)
on datetimes between 06:00 and 08:00, there would be a 75%
probability of generating a datetime; for example, there would be a
75% chance that I would generate the 06:05, 06:10 or 06:15 datetime
...
... and so the process would continue throughout the day, with other time bands, with different probabilities, but following this same reasoning.
Could anyone say if it is possible to do this, and if so, how to generate this data programmatically?
Store the information of "time bands" in an appropriate format first.
Start with the "cursor" variable at 00:00 of a day.
Use while loop to iterate over increasing "cursor". Increment "cursor" for 5 minutes, and loop while "cursor" is smaller than the next day's 00:00.
In the loop, check the time bands to get the band and the probability for the "cursor". Use random.random() to roll the dice and add the "cursor" to the list accordingly.
Here is my version of the implementation.
https://www.pythonpad.co/pads/2rzmd1hfyrwmehhs/

Python Arrow Not Formatting Date Properly

I am using the Python Arrow package for formatting a date that I've got.
My input is:
datetime=2017-10-01T00:10:00Z and timezone=US/Pacific
My expected output is:
Sun 10/01 # 6:10pm
I've tried a host of different date time conversions but I always end up with Sun 10/01 # 12:10AM which is not time zone dependent.
If I try and say:
x = arrow.Arrow.strptime('2017-10-01T00:10:00Z',
'%Y-%m-%dT%H:%M:%SZ',
tzinfo=tz.gettz('US/Pacific'))
x is equal to:
<Arrow [2017-10-01T00:10:00-07:00]>
I then say:
x.strftime('%a %m/%d # %I:%M%p')
and it outputs
Sun 10/01 # 12:10AM
The Arrow object knows about the timezone as evidenced by the -7:00 but does not format the date accordingly.
Any ideas?
I think that there are a couple of misunderstandings in this question.
Convert to a timezone
I can see no way that the timestamp,
2017-10-01T00:10:00Z and timezone=US/Pacific
Can become,
Sun 10/01 # 6:10pm
There are several problems here.
The Z at the end of the timestamp is a timezone and means Zulu aka GMT, so the timestamp already has a timezone.
If we ignore problem #1, then for that timestamp 10 minutes after midnight (minus the Z) to become 6:10 pm the same day would require a timezone that was +18. This timezone does not exist.
US/Pacific is -7/-8 depending on the time of the year. If we accept the Z as the timezone and want to convert to US/Pacific, then the time should be 9/31 at 5:10pm
What does -7:00 mean?
So I am going to guess that what you intend is that the timestamp is in fact Zulu, and you want to display that timestamp as US/Pacific. If this is true than you need to do:
from dateutil import tz
import arrow
x = arrow.Arrow.strptime(
'2017-10-01T00:10:00Z',
'%Y-%m-%dT%H:%M:%SZ').to(tz.gettz('US/Pacific'))
print(x)
print(x.strftime('%a %m/%d # %I:%M%p'))
This results in:
2017-09-30T17:10:00-07:00
Sat 09/30 # 05:10PM
You will note, as you noted earlier, that these produce the same time. The difference is that the first also has a -7:00. This does not indicate, as you intimated in your question, that time needs to have 7 hours removed to be shown as in the timezone, it instead indicates that the timestamp has already had 7 hours removed from Zulu.

Sorting scheduled events python

So I have list of events that are sort of like alarms. They're defined by their start and end time (in hours and minutes), a range of days (ie 1-3 which is sunday through wed.), and a range of months (ie 1-3, january through march). The format of that data is largely unchangeable. I need to, not necessarily sort the list, but I need to find the next upcoming event based on the current time. There's just so many different ways to do this and so many different corner cases. This is my pseudo code:
now = time()
diff = []
# Start difference between now and start times
for s in schedule #assuming appending to diff
diff.minutes = s.minutes - time.minutes #
diff.hours = s.hours - time.hours
diff.days = s.days - time.days
diff.months = s.months - time.months
for d in diff
if d < 0
d = period + d
# period is the maximum period of the attribute. ie minutes is 60, hours is 24
# repeat for event end times
So now I have a list of tuples of differences in hours, minutes, days, and weeks. This tuple already takes into account if it's passed the start time, but before the end time. So let's say it's in August and the start month of the event is July and the end month is September, so diff.month == 0.
Now this specific corner case is giving me trouble:
Let's say a schedule runs from 0 to 23:59 thursdays in august. And it's Friday the 27th. Running my algorithm, the difference in months would be 0 when in reality it won't run again until next august, so it should be 12. And I'm stuck. The month is the only problem I think because the month is the only attribute that directly depends on what the date of the specific month is (versus just the day). Is my algorithm OK and I can just deal with this special case? Or is there something better out there for this?
This is the data I'm working with
map['start_time']=''
map['end_time']=''
map['start_moy']=''
map['end_moy']=''
map['start_dow']=''
map['end_dow']=''
The schedule getAllSchedules method just returns a list to all of the schedules. I can change the schedule class but I'm not sure what difference I can make there. I can't add/change the format of the schedules I'm given
Convert the items from the schedule into datetime objects. Then you can simply sort them
from datetime import datetime
events = sorted(datetime(s.year, s.month, s.day, s.hour, s.minute) for s in schedule)
Since your resolution is in minutes, and assuming that you don't have many events, then I'd simply scan all the events every minute.
Filter your events so that you have a new list where the event range match the current month and day.
Then for each of those events declare that they are active or inactive according to whether the current time matches the event's range.
The primary issue seems to be with the fact that you're using the day of the week, instead of explicit days of the month.
While your cited edge case is one example, does this issue not crop up with all events scheduled in any month outside of the current one?
I think the most robust approach here would be to do the work to get your scheduled events into datetime format, then use #gnibbler's suggestion of sorting the datetime objects.
Once you have determined that the last event for the current month has already passed, calculate the distance to the next month the event occurs in (be it + 1 year, or just + 1 month), then construct a datetime object with that information:
first_of_month = datetime.date(calculated_year, calculated_month, 1)
By using the first day of the month, you can then use:
day_of_week = first_of_month.strftime('%w')
To give you what day of the week the first of that month falls on, which you can then use to calculate how many days to add to get to the first, second, third, etc. instance of a given day of the week, for that month. Once you have that day, you can construct a valid datetime object and do whatever comparisons you wish with now().
I couldn't figure out how to do it using only datetimes. But I found a module and used this. It's perfect
http://labix.org/python-dateutil

Categories