0

EDIT

Further to the other below info and thanks to some helpful input the issue is caused by using strftime %s to generate a Unix Timestamp (which is what the system being queried requires). Strftime %s is not compatible with the Windows platform therefore I need to use an alternative method to generate the Unix Timestamp. Jez has suggested time.time() which I have experimented with but I'm clearly not doing it right somewhere along the way. I need to change this section of code from using strftime to time():

    if (args.startdate):
       from_time=str(int(args.startdate.strftime('%s')) * 1000)
    if (args.enddate):
       to_time=str(int(args.enddate.strftime('%s')) * 1000)

Any help or a steer greatly appreciated. :)

/EDIT

I've been given a Python script which appears to run ok when deployed on an Apple laptop but gives an error message when I run it on a Windows machine. I need to talk a 3rd party through executing the file remotely and he only has a windows machine so I need to try and figure out why it isn't working. I'm running 2.7 for reference. This section appears to be where the error is being caused:

if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('-s', "--startdate", help="The start date (included)- format YYYY-MM-DD -- if not specified then earliest available data", type=valid_date)
parser.add_argument('-e', "--enddate", help="The end date (excluded) - format YYYY-MM-DD  -- if not specified then 'now'", type=valid_date)
parser.add_argument('-u', "--user", help="User name to use", default='admin')
parser.add_argument('-p', "--password", help="Password for user", default='redwood')
parser.add_argument('-a', "--attribute", help="Attribute", choices=['temperature', 'motion', 'input-power', 'output-power'], default='motion')
parser.add_argument('host', help='Hostname/IP address of engine to connect to', default='127.0.0.1')
args = parser.parse_args()
    user = args.user    
    passwd = args.password
    if (args.startdate):
       from_time=str(int(args.startdate.strftime('%s')) * 1000)
    if (args.enddate):
       to_time=str(int(args.enddate.strftime('%s')) * 1000)

    scale=1
    unit='seconds since 1.1.1970'
    if (args.attribute == 'temperature'):
       path=temperature_path
       scale = 100
       unit = "Degrees Celsius"
    elif (args.attribute == 'output-power'):
       path=opower_path
       scale = 100
       unit = "Watts"
    elif (args.attribute == 'input-power'):
       path=ipower_path
       scale = 1000
       unit = "Watts"
    else:
       path=motion_path
    print "Epoch Time, Local Time (this machine), Attribute, Value (%s) " % unit
query_stats(args.host)

This is the command I'm using to execute:

C:\Python27>python stats_query.py -s 2016-03-18 -e 2016-03-19 -u admin -p admin -a motion 192.168.2.222

And this is the error message I get:

Traceback (most recent call last):
File "stats_query.py", line 132, in <module>
from_time=str(int(args.startdate.strftime('%s')) * 1000)
ValueError: Invalid format string

If anyone has any thoughts I'd greatly appreciate any feedback. Apologies if I'm asking a stupid question - I'm really not very familiar with Python.

5
  • 3
    possible duplicate of stackoverflow.com/questions/10807164/… Commented May 9, 2016 at 13:51
  • Not as far as I can see. Commented May 9, 2016 at 14:07
  • Be cautious using the solutions offered here: yes, changing to '%S' will make the code run without an exception, but your from_time will then only ever be a number from 0 to 59 (the "seconds" part of a formatted time). That's fairly useless as a baseline from which to measure elapsed time, because of wraparounds. You may simply want time.time() instead of anything to do with strftime Commented May 9, 2016 at 14:18
  • Thanks Jez, You're exactly right. Having done some more research the complete list of arguments shows %S and %s are entirely different functions. Basically the system is using unix time and it appears that windows doesn't support the %s argument which specifically relates to the unix time epoch. The manual states: %s Unix Epoch Time timestamp (same as the time() function) Am I correct in assuming that I should be able to utilise the time() function as an alternative? Commented May 10, 2016 at 13:44
  • I have changed to this but still get an error back/; if (args.startdate): from_time=str(int(args.startdate.time.time) * 1000) if (args.enddate): to_time=str(int(args.enddate.time.time) * 1000) Commented May 10, 2016 at 19:20

3 Answers 3

1

If you want to print this in seconds, use %S (with a capital S).

Sign up to request clarification or add additional context in comments.

1 Comment

I did try this but I got a different response which didn't help either so I changed it back again. It simply responded with: Epoch Time, Local Time (this machine), Attribute, Value (seconds since 1.1.1970)
0

(Should maybe be a comment)

As others have mentioned already, not all directives are available on all platforms.

Python's documentation lists all directives which are cross-platform: https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior

5 Comments

OK Thanks, I did check this stuff previously and %S does appear to be in the list of cross platform directives so I'm not sure what I'm looking for here?
%S (upper case S) is on this list, but your code uses %s (smaller case s)
Ok something that has jumped out at me is this: Because the format depends on the current locale, care should be taken when making assumptions about the output value. Field orderings will vary (for example, “month/day/year” versus “day/month/year”) This was written by a guy in the states and I'm in the UK so is it possible that the date format will be different based on my PC's settings?
@RobinS Not in this case. %S will always output the seconds, as %m will always output the month.
I'm wondering if the error is with the 'startdate' variable rather than the '%s'? If I leave out the date range in my command line it works correctly - i.e. it drops 2 years worth of data out. When I add the start and end date it gives the error message.
0

Not sure what valid_time is in your function, but if you use something like:

def valid_time(t):
    format = "%Y-%m-%d"
    datetime.datetime.strptime(t, format)

It gets past the issue you are describing... after that, I see other issues, since motion_path is not defined.

UPDATE: The following code works running on Windows7 Professional using python 2.7 (file saved as tryme.py)

import argparse
import datetime

def motion_path():
  print "Got here.. no issues"

def query_stats(host):
  print "We'll query the host: %s" % host

def valid_time(t):
  format = "%Y-%m-%d"
  return datetime.datetime.strptime(t, format)

if __name__ == "__main__":
  parser = argparse.ArgumentParser()
  parser.add_argument('-s', "--startdate", help="The start date (included)- format YYYY-MM-DD -- if not specified then earliest available data", type=valid_time)
  parser.add_argument('-e', "--enddate", help="The end date (excluded) - format YYYY-MM-DD  -- if not specified then 'now'", type=valid_time)
  parser.add_argument('-u', "--user", help="User name to use", default='admin')
  parser.add_argument('-p', "--password", help="Password for user", default='redwood')
  parser.add_argument('-a', "--attribute", help="Attribute", choices=['temperature', 'motion', 'input-power', 'output-power'], default='motion')
  parser.add_argument('host', help='Hostname/IP address of engine to connect to', default='127.0.0.1')
  args = parser.parse_args()
  user = args.user  
  epoch = datetime.datetime.utcfromtimestamp(0)
  passwd = args.password
  if (args.startdate):
     from_time=str(int((args.startdate-epoch).total_seconds()))
  if (args.enddate):
     to_time=str(int((args.enddate-epoch).total_seconds()))

  print 'From: %s\nTo: %s\n' %(from_time, to_time)

  scale=1
  unit='seconds since 1.1.1970'
  if (args.attribute == 'temperature'):
     path=temperature_path
     scale = 100
     unit = "Degrees Celsius"
  elif (args.attribute == 'output-power'):
     path=opower_path
     scale = 100
     unit = "Watts"
  elif (args.attribute == 'input-power'):
     path=ipower_path
     scale = 1000
     unit = "Watts"
  else:
     path=motion_path
  print "Epoch Time, Local Time (this machine), Attribute, Value (%s) " % unit
  query_stats(args.host)

The command used to run it:

C:\Python27>python tryme.py -s 2016-03-18 -e 2016-03-19 -u admin -p admin -a motion 192.168.2.222

The results:

Epoch Time, Local Time (this machine), Attribute, Value (seconds since 1.1.1970)
We'll query the host: 192.168.2.222

3 Comments

This is what I have: def valid_date(s): try: return datetime.strptime(s, "%Y-%m-%d") except ValueError: msg = "Not a valid date (YYYY-MM-DD): '{0}'.".format(s) raise argparse.ArgumentTypeError(msg)
The motion_path is defined further up the script - I have only included an excerpt as I thought the problem would be fairly obvious to someone that was familiar with Python. The script executes fine if I take out the -s and -e arguments. If I change the date format it gives me an error to say I've entered the date in the wrong format so that's not the issue either!
There is your alternate way to get a unix timestamp (seconds from epoch time).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.