www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - how to parse a string into a phobos datatype with additional logic

reply yawniek <dlang srtnwz.com> writes:
what is the way one is supposed to parse e.g. a
double of unixtime (as delived by nginx logs) into a SysTime?

currently i'm creating a wrapper struct around SysTime with alias 
this as:

https://gist.github.com/yannick/6caf5a5184beea0c24f35d9d4a4c7783

really ugly imho.

is there a better way to do this?
Apr 07 2016
next sibling parent reply Edwin van Leeuwen <edder tkwsping.nl> writes:
On Thursday, 7 April 2016 at 07:45:06 UTC, yawniek wrote:
 what is the way one is supposed to parse e.g. a
 double of unixtime (as delived by nginx logs) into a SysTime?

 currently i'm creating a wrapper struct around SysTime with 
 alias this as:

 https://gist.github.com/yannick/6caf5a5184beea0c24f35d9d4a4c7783

 really ugly imho.

 is there a better way to do this?
You can try this library: https://code.dlang.org/packages/dateparser
Apr 07 2016
parent yawniek <dlang srtnwz.com> writes:
On Thursday, 7 April 2016 at 08:03:34 UTC, Edwin van Leeuwen 
wrote:
 You can try this library:
 https://code.dlang.org/packages/dateparser
nope this will not work and the question is broader: i want to have a standard datatype parsed in a specific way and so that i can use other std library tools such as csvparser to then do the job. parsing unixtime with subsecond resolution was just one example, there is a lot of cases where you want to do some tranformation e.g. "33%" -> 0.33f my solution with defining a custom struct works, but it would be nice if you somehow could hook into this process in a cleaner way.
Apr 07 2016
prev sibling next sibling parent reply Puming <zhaopuming gmail.com> writes:
On Thursday, 7 April 2016 at 07:45:06 UTC, yawniek wrote:
 what is the way one is supposed to parse e.g. a
 double of unixtime (as delived by nginx logs) into a SysTime?

 currently i'm creating a wrapper struct around SysTime with 
 alias this as:

 https://gist.github.com/yannick/6caf5a5184beea0c24f35d9d4a4c7783

 really ugly imho.

 is there a better way to do this?
you mean http://dlang.org/phobos/std_datetime.html#.SysTime.fromUnixTime ?
Apr 07 2016
parent reply Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
On Thursday, 7 April 2016 at 08:06:03 UTC, Puming wrote:
 On Thursday, 7 April 2016 at 07:45:06 UTC, yawniek wrote:
 what is the way one is supposed to parse e.g. a
 double of unixtime (as delived by nginx logs) into a SysTime?

 currently i'm creating a wrapper struct around SysTime with 
 alias this as:

 https://gist.github.com/yannick/6caf5a5184beea0c24f35d9d4a4c7783

 really ugly imho.

 is there a better way to do this?
you mean http://dlang.org/phobos/std_datetime.html#.SysTime.fromUnixTime ?
That one only accepts `long`, though, so you'd lose sub-second precision.
Apr 07 2016
parent Puming <zhaopuming gmail.com> writes:
On Thursday, 7 April 2016 at 11:07:35 UTC, Marc Schütz wrote:
 On Thursday, 7 April 2016 at 08:06:03 UTC, Puming wrote:
 On Thursday, 7 April 2016 at 07:45:06 UTC, yawniek wrote:
 what is the way one is supposed to parse e.g. a
 double of unixtime (as delived by nginx logs) into a SysTime?

 currently i'm creating a wrapper struct around SysTime with 
 alias this as:

 https://gist.github.com/yannick/6caf5a5184beea0c24f35d9d4a4c7783

 really ugly imho.

 is there a better way to do this?
you mean http://dlang.org/phobos/std_datetime.html#.SysTime.fromUnixTime ?
That one only accepts `long`, though, so you'd lose sub-second precision.
Yes, might be due to that standard UnixTime only has second precision. For the sub-second part, you need to add a duration like nsecs. It's still ugly, but you don't need another struct if what you want is just a SysTime. SysTime parseNginxTime(string t) { // assuming the nginx time has precision of nano-seconds. return SysTime.fromUnixTime(t[0..$-9].to!long) + t[$-9..$].to!long.nsecs; } The problem though is that SysTime only hode precision to the hnsec, so the last three digits is actually lost.
Apr 07 2016
prev sibling parent reply Jonathan M Davis via Digitalmars-d-learn writes:
On Thursday, April 07, 2016 07:45:06 yawniek via Digitalmars-d-learn wrote:
 what is the way one is supposed to parse e.g. a
 double of unixtime (as delived by nginx logs) into a SysTime?

 currently i'm creating a wrapper struct around SysTime with alias
 this as:

 https://gist.github.com/yannick/6caf5a5184beea0c24f35d9d4a4c7783

 really ugly imho.

 is there a better way to do this?
Functions like format, to, etc. all use toString and constructors when dealing with conversions to and from string. There is no way to provide a custom conversion function for them to use with a type instead of what's built into the type. So, if you want this to be automatic as you pass the type around, then AFAIK, your solution is really the only solution. Certainly, you can create a custom conversion function and use it in your own code, but nothing else is going to know about it or use it. But honestly, I don't see how we even _could_ make it possible to provide a custom conversion function except for having another argument (either an alias template argument, or a function argument which is a delegate), and that would mean that everything that might use such a conversion function would have to accept it. That might work for something like std.conv.to, but once you're dealing with something like the CSVParser, what's it going to do? Have every function that might use such a conversion take a template argument for the conversion function so that it could pass it on to std.conv.to or std.conv.parse? And what of code that then uses CSVParser? Does it need to then accept and pass on such conversion functions? And what if you need more than one conversion function, because you're dealing with multiple types that you want to convert differently than normal? I just don't see how that scales. Really, as annoying as it may be to wrap the type in another type just to get the conversion, it's by far the cleanest way to do it. I just don't see how we even _could_ do in a sane way that involved any kind of free function. That would be like trying to arbitrarily add a constructor or overloaded operator to a type and have all other code magically use it, which is pretty much impossible given D's compilation model (e.g. the type could be being used in a library that was already compiled when you try and use it in your program), and how on earth would you deal with conflicts? If two different modules both tried to add a constructor or overloaded operator to a type, and those conflicted, how would other code know which to use - especially when this is supposed to be invisible to them? So, while I understand your frustration, I just don't see any other sane way to approach this problem than what you've done. Putting it all in a wrapper type encapsulates it in a way that it can actually work, whereas the other options get messy really fast if they're possible at all. - Jonathan M Davis
Apr 07 2016
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 04/07/2016 11:29 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Thursday, April 07, 2016 07:45:06 yawniek via Digitalmars-d-learn wrote:
 what is the way one is supposed to parse e.g. a
 double of unixtime (as delived by nginx logs) into a SysTime?

 currently i'm creating a wrapper struct around SysTime with alias
 this as:

 https://gist.github.com/yannick/6caf5a5184beea0c24f35d9d4a4c7783

 really ugly imho.

 is there a better way to do this?
Functions like format, to, etc. all use toString and constructors when dealing with conversions to and from string. There is no way to provide a custom conversion function for them to use with a type instead of what's built into the type.
I think FormatSpec (and the undocumented FormatElement?) comes close: http://dlang.org/phobos/std_format.html#.FormatSpec Ali
Apr 07 2016
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 04/07/2016 11:35 AM, Ali Çehreli wrote:
 On 04/07/2016 11:29 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
 On Thursday, April 07, 2016 07:45:06 yawniek via Digitalmars-d-learn
 wrote:
 what is the way one is supposed to parse e.g. a
 double of unixtime (as delived by nginx logs) into a SysTime?

 currently i'm creating a wrapper struct around SysTime with alias
 this as:

 https://gist.github.com/yannick/6caf5a5184beea0c24f35d9d4a4c7783

 really ugly imho.

 is there a better way to do this?
Functions like format, to, etc. all use toString and constructors when dealing with conversions to and from string. There is no way to provide a custom conversion function for them to use with a type instead of what's built into the type.
I think FormatSpec (and the undocumented FormatElement?) comes close: http://dlang.org/phobos/std_format.html#.FormatSpec Ali
I don't agree with myself anymore. :) Ail
Apr 07 2016
prev sibling parent yawniek <dlang srtnwz.com> writes:
On Thursday, 7 April 2016 at 18:29:19 UTC, Jonathan M Davis wrote:
 On Thursday, April 07, 2016 07:45:06 yawniek via 
 Digitalmars-d-learn wrote:
 So, while I understand your frustration, I just don't see any 
 other sane way to approach this problem than what you've done. 
 Putting it all in a wrapper type encapsulates it in a way that 
 it can actually work, whereas the other options get messy 
 really fast if they're possible at all.

 - Jonathan M Davis
thank you Jonathan for the extensive answer, really helpful. And the Longer i think about it the more i come to the conclusion that its actually not even that ugly as it allows you to easily add more logic to the structs if needed. i already extensively alias standard datatypes to another name where it is used in a specific context (latest example: alias ColumnName = string) and it became helpful because you can easily refactor it to something bigger.
Apr 07 2016