简体   繁体   中英

string convert to datetime timezone

I want to linear interpolation some points between two time string.

So I try to convert string to datetime then insert some point then convert datetime to string. but it seems the timezone not correct.

In below example. I wish to insert one point between 9-28 11:07:57.435" and "9-28 12:00:00.773".

#!/usr/bin/env python
import numpy as np
from time import mktime
from datetime import datetime

#-----------------------------------------#
def main():
    dtstr = [
"9-28 11:07:57.435",
"9-28 12:00:00.773"
]
    print "input",dtstr
    dtlst = str2dt(dtstr)
    floatlst = dt2float(dtlst)

    bins = 3
    x1 = list(np.arange(floatlst[0],floatlst[-1],(floatlst[-1]-floatlst[0])/bins))
    dtlst = float2dt(x1)
    dtstr = dt2str(dtlst)
    print "output",dtstr
    return

def str2dt(strlst):
    dtlst = [datetime.strptime("2014-"+i, "%Y-%m-%d %H:%M:%S.%f") for i in strlst]
    return dtlst

def dt2float(dtlst):
    floatlst = [mktime(dt.timetuple()) for dt in dtlst]
    return floatlst

def dt2str(dtlst):
    dtstr = [dt.strftime("%Y-%m-%d %H:%M:%S %Z%z") for dt in dtlst]
    return dtstr

def float2dt(floatlst):
    dtlst = [datetime.utcfromtimestamp(seconds) for seconds in floatlst]
    return dtlst

#-----------------------------------------#
if __name__ == "__main__":
    main()

The output looks like:

input ['9-28 11:07:57.435', '9-28 12:00:00.773']
output ['2014-09-28 16:07:57 ', '2014-09-28 16:25:18 ', '2014-09-28 16:42:39 ']

Two questions here:

  1. The input and output has 4 hours differ (9-28 16:07:57 to 9-28 11:07:57). I guess it caused by timezone but not sure how to fix it.
  2. I wish the first and last point the same as input, but now it seems the last point is less than the input last point (16:42:39 vs 12:00:00).

Q1. You're right about the timezones, you're using time.mktime which converts struct_time to seconds assuming the input is local time , but then using datetime.utcfromtimestamp which (naturally) converts to utc. Use datetime.fromtimestamp instead to keep everything in local time.

Q2. As with the native Python range / xrange , when you do numpy.arange(x, y, z) , the result starts with x and goes upto, but not including y ( except in weird floating point roundoff cases. Don't rely on this behaviour) . if you want consistent behaviour on the end points w/ floating values, use numpy.linspace

On the other hand, why convert datetime to seconds, then go back again? datetime objects support addition and subtraction. Below would be my suggestion.

from time import mktime, localtime
from datetime import datetime
from copy import copy

def main():
    input_timestrings = ["9-28 11:07:57.435", "9-28 12:00:00.773"]
    input_datetimes = timestrings_to_datestimes(input_timestrings)

    start_datetime = input_datetimes[0]
    end_datetime = input_datetimes[1]

    # subtraction between datetime objects returns a timedelta object
    period_length = end_datetime - start_datetime

    bins = 3

    # operation w/ timedelta objects and datetime objects work pretty much as you'd expect it to
    delta = period_length / bins
    datetimes = list(custom_range(start_datetime, end_datetime + delta, delta))
    output_timestrings = datetimes_to_timestrings(datetimes)

    print output_timestrings
    return

def timestrings_to_datetimes(timestrings):
    datetimes = [datetime.strptime("2014-"+timestring, "%Y-%m-%d %H:%M:%S.%f") for timestring in timestrings]
    return datetimes

def datetimes_to_timestrings(datetimes):
    timestrings = [datetime_.strftime("%Y-%m-%d %H:%M:%S %Z%z") for datetime_ in datetimes]
    return timestrings

def custom_range(start, end, jump):
    x = start
    while x < end:
        yield x
        x = x + jump


if __name__ == "__main__":
    main()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM