OK, to avoid altering the gluon code, I'll change the model to use a
long int to represent epoch-milliseconds

On Jun 30, 7:03 am, mdipierro <mdipie...@cs.depaul.edu> wrote:
> I am afraid including microsecods will break the datepicker calendar.
>
> On Jun 30, 2:13 am, Dan <danbr...@gmail.com> wrote:
>
> > Thanks for the suggestion Massimo.
>
> > It looks like the GAE code is working properly, at least for inserting
> > the data (see below for details on how I tested this). The truncation
> > for displaying GAE datetime values was happening in the as_list()
> > function in the sql.py file [line 2346], and when I removed that step
> > from my code I could work with information in GAE's datastore with
> > micro-second precision.
>
> > However, it took more work to get fractional seconds working for
> > SQLite. Here is a description of the changes I made to the code in
> > sql.py.
>
> > Truncation of fractional seconds happens during both insertion and
> > reading from the database.
>
> > To fix insertion, I changed line 409 from this:
> >                 obj = obj.strftime('%Y-%m-%d %H:%M:%S')
> > to this:
> >                 if obj.microsecond > 0:
> >                     obj = obj.strftime('%Y-%m-%d %H:%M:%S') + '.' + str
> > (obj.microsecond).zfill(6)
> >                 else:
> >                     obj = obj.strftime('%Y-%m-%d %H:%M:%S')
>
> > To fix reading from the database, I added these lines after 2302:
> >                 ms = 0 # default
> >                 if (len(str(value)) > 19) and (str(value)[19] == '.'):
> >                     dec = str(value).rfind('.')
> >                     dec_end = len(str(value))
> >                     if 18 < dec < dec_end:
> >                         ms = int(int(str(value)[dec+1:dec_end]) * pow
> > (10,(7-dec_end+dec)) )
> > and I changed this line:
> >                 row[tablename][fieldname] = datetime.datetime(y, m, d,
> > h, mi, s)
> > to be this:
> >                 row[tablename][fieldname] = datetime.datetime(y, m, d,
> > h, mi, s, ms)
>
> > If I'm interpreting the sql.py code correctly, this issue probably
> > affects all of the other databases - I didn't change any of the
> > special-case code for datetime support for other types of databases,
> > or for the time data type. And I didn't change the IS_DATETIME()
> > function in validators.py either.
>
> > Note that these routines could be simplified when operating with
> > python2.6:
> > "New in version 2.6: time and datetime objects support a %f format
> > code which expands to the number of microseconds in the object, zero-
> > padded on the left to six places." (http://docs.python.org/library/
> > datetime.html)
> > For python2.5, it's possible to use the datetime's microsecond
> > attribute to get the information.
>
> > Dan
>
> > For future reference by GAE developers (including myself):
> > Using the GAE development console (http://localhost:8080/_ah/admin/
> > interactive), I could run a quick set of lines to get the actual
> > values stored in the GAE datastore, which indeed contain the full
> > precision of what I inserted. These are the lines that I used:
>
> > import datetime as datetime
> > from google.appengine.ext import db
> > class timetest(db.Model):
> >   starttime = db.DateTimeProperty()
> >   endtime = db.DateTimeProperty()
> > qry = db.Query(timetest)
> > rows = qry.fetch(limit=5)
> > for r in rows:
> >   print r.starttime
>
> > which produced these results, including some fractional seconds:
> > 1970-01-01 00:00:44.400000
> > 1970-01-01 00:00:12.200000
>
> > On Jun 29, 6:55 pm, mdipierro <mdipie...@cs.depaul.edu> wrote:
>
> > > correction. not print statements on GAE but logging statetements.
>
> > > On Jun 29, 8:54 pm, mdipierro <mdipie...@cs.depaul.edu> wrote:
>
> > > > In gluon/contrib/gql.py web2py does this:
>
> > > >             if field.type == 'datetime' and value != None and not
> > > > isinstance(value, datetime.datetime):
> > > >                 (y, m, d) = [int(x) for x in
> > > >                              str(value)[:10].strip().split('-')]
> > > >                 time_items = [int(x) for x in
> > > >                               str(value)[11:].strip().split(':')[:3]]
> > > >                 if len(time_items) == 3:
> > > >                     (h, mi, s) = time_items
> > > >                 else:
> > > >                     (h, mi, s) = time_items + [0]
> > > >                 row[tablename][fieldname] = datetime.datetime
> > > > (y,m,d,h,mi,s)
> > > >                 ....
> > > >             else:
> > > >                 row[tablename][fieldname] = value
>
> > > > perhaps you can put some print statements and see what "value" vs what
> > > > it should be.
>
> > > > Massimo
>
> > > > On Jun 29, 8:36 pm, Dan <danbr...@gmail.com> wrote:
>
> > > > > Here is some sample code to produce the behavior I'm trying to
> > > > > describe. Note that in the controller, there are 2 lines commented out
> > > > > because they return an error ("TypeError: unsupported operand type(s)
> > > > > for -: 'str' and 'str'")
>
> > > > > db.define_table('timetest',
> > > > >     db.Field('starttime','datetime',default=request.now),
> > > > >     db.Field('endtime','datetime',default=request.now),
> > > > > )
>
> > > > > def timetest():
> > > > >     form=FORM(TABLE(
> > > > >         TR("Start time (Epoch Seconds UTC):",INPUT
> > > > > (_type="text",_name="start_time_es")),
> > > > >         TR("End time (Epoch Seconds UTC):",INPUT
> > > > > (_type="text",_name="end_time_es")),
> > > > >         TR("",INPUT(_type="submit",_value="Submit"))
> > > > >     ))
>
> > > > >     rowtoinsert = {}
> > > > >     if form.accepts(request.vars):
> > > > >         response.flash="form accepted input"
> > > > >         startdatetime = datetime.datetime.utcfromtimestamp(float
> > > > > (form.vars.start_time_es))
> > > > >         enddatetime = datetime.datetime.utcfromtimestamp(float
> > > > > (form.vars.end_time_es))
> > > > >         # make the database insertion
> > > > >         rowtoinsert={
> > > > >             'starttime':startdatetime,
> > > > >             'endtime':enddatetime,
> > > > >             }
> > > > >         idinserted = db.timetest.insert(**rowtoinsert)
> > > > >     elif form.errors:
> > > > >         response.flash="form is invalid"
>
> > > > >     existing_rows = db(db.timetest.id>0).select().as_list()
> > > > > #    for r in existing_rows:
> > > > > #        r['time_difference'] = r['endtime'] - r['starttime']
>
> > > > >     return dict(form=form,
> > > > >         rowtoinsert=rowtoinsert,
> > > > >         existing_rows=existing_rows)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"web2py Web Framework" group.
To post to this group, send email to web2py@googlegroups.com
To unsubscribe from this group, send email to 
web2py+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/web2py?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to