digitalmars.D.learn - SysTime in a Struct
- albatroz (28/28) Mar 01 2012 Hi,
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (11/40) Mar 01 2012 That is a separate local variable within this(this). Also, this(this) is...
- albatroz (26/30) Mar 01 2012 No, but not using this(this) will fail to build with:
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (23/55) Mar 01 2012 So you are trying to initialize the member with a default initializer,
- albatroz (9/15) Mar 01 2012 Hi Ali, just tring to define a type that holds this information.
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (69/75) Mar 01 2012 From that description, it looks like you can hold edate etc. as members...
- Jonathan M Davis (12/102) Mar 01 2012 You know, you can create a TimeOfDay from "15:53:00" with
- albatroz (6/87) Mar 06 2012 Hi Ali,
- Jonathan M Davis (9/42) Mar 01 2012 A default-initialized SysTime is useless. It hasn't been properly initia...
Hi, I have defined this struct struct preEv { string edate; //010112 string etime; //00:00:00 string etext; // SysTime esystime; this (this) { SysTime esystime = SysTime(DateTime( Clock.currTime.year, to!int(this.edate[2..4]), to!int(this.edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8]))); } } If I write to the sctruct and then print it I'm able to see the SysTime variable with a value. writeln(preEv) //previousEvents("140212", "05:13:26", "9 140212 05:13:26 d", "2012-Feb-14 05:13:26") but if trying to get the value from the SysTime variable I get a Segmentation fault. Trying to read any other variable inside this struct will not be a problem. writeln (preEv.esystime.day) // will compile but segfaults On DMD32 D Compiler v2.058 Any correct way to do this? Thank you.
Mar 01 2012
On 03/01/2012 06:15 AM, albatroz wrote:Hi, I have defined this struct struct preEv { string edate; //010112 string etime; //00:00:00 string etext; // SysTime esystime;That is a member of this type.this (this) { SysTime esystime = SysTime(DateTime(That is a separate local variable within this(this). Also, this(this) is the postblit (similar to a copy constructor). Is that what you want to define? I think you want to simply do this anyway: esystime = or this: this.esystime =Clock.currTime.year, to!int(this.edate[2..4]), to!int(this.edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8]))); } } If I write to the sctruct and then print it I'm able to see the SysTime variable with a value. writeln(preEv) //previousEvents("140212", "05:13:26", "9 140212 05:13:26 d", "2012-Feb-14 05:13:26") but if trying to get the value from the SysTime variable I get a Segmentation fault.Probably because esystime member is no initialized.Trying to read any other variable inside this struct will not be a problem. writeln (preEv.esystime.day) // will compile but segfaults On DMD32 D Compiler v2.058 Any correct way to do this? Thank you.Ali
Mar 01 2012
Have fixed the segfault by using DateTime instead of SysTime.That is a separate local variable within this(this). Also, this(this) is the postblit (similar to a copy constructor). Is that what you want to define?No, but not using this(this) will fail to build with: static variable _initialized cannot be read at compile time Making the struct similar to what you suggest will work. struct prevEv { string edate; string etime; string etext; DateTime edatetime; this (this) { edatetime = DateTime( Clock.currTime.year, to!int(this.edate[2..4]), to!int(this.edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8])); } } Just not has expected, do you have any suggestion how to do it properly? writeln ( prevEv.edatetime ); //0001-Jan-01 00:00:00 writeln ( prevEv ); // preEv("140212", "05:13:26", "9 140212 05:13:26 d", 2012-Feb-14 05:13:26)AliThanks
Mar 01 2012
On 03/01/2012 09:14 AM, albatroz wrote:Have fixed the segfault by using DateTime instead of SysTime.So you are trying to initialize the member with a default initializer, like this: struct prevEv { // ... DateTime edatetime = DateTime(/* ... */); } For that to work, the initial value must be a compile-time value. I am not sure that you want that. Also, this(this) is needed in very rare cases. Are you trying to create objects of prevEv? Then you should use this(). Unfortunately, structs cannot have default constructors. A solution might be to use a function that makes and returns a prevEv: prevEv make_prevEv() { return prevEv(/* ... */, DateTime(/* ... */)); }That is a separate local variable within this(this). Also, this(this) is the postblit (similar to a copy constructor). Is that what you want to define?No, but not using this(this) will fail to build with: static variable _initialized cannot be read at compile timeMaking the struct similar to what you suggest will work. struct prevEv { string edate; string etime; string etext; DateTime edatetime; this (this) { edatetime = DateTime( Clock.currTime.year, to!int(this.edate[2..4]), to!int(this.edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8])); } } Just not has expected, do you have any suggestion how to do it properly?Are you trying to record the time when a prevEv is copied from another one? If not, I suggest not defining this(this). It is the postblit, to make things right for rare structs and only when the compiler generated copying is wrong for a that type. Or, are you just trying to define a type that contains time information?writeln ( prevEv.edatetime ); //0001-Jan-01 00:00:00 writeln ( prevEv ); // preEv("140212", "05:13:26", "9 140212 05:13:26 d", 2012-Feb-14 05:13:26)AliAliThanks
Mar 01 2012
Are you trying to record the time when a prevEv is copied from another one? If not, I suggest not defining this(this). It is the postblit, to make things right for rare structs and only when the compiler generated copying is wrong for a that type. Or, are you just trying to define a type that contains time information?Hi Ali, just tring to define a type that holds this information. It was just an attempt to create a type DateTime with the values from the known strings, I thought it was possible to create the definition directly in the Struct, with no need for an external function. edate and etime are strings that I will read in to the struct, but for operations with time and dates I need to create/define a DateTime type. Thanks
Mar 01 2012
On 03/01/2012 03:46 PM, albatroz wrote:Hi Ali, just tring to define a type that holds this information. It was just an attempt to create a type DateTime with the values from the known strings, I thought it was possible to create the definition directly in the Struct, with no need for an external function. edate and etime are strings that I will read in to the struct, but for operations with time and dates I need to create/define a DateTime type.From that description, it looks like you can hold edate etc. as members and produce SysTime as needed. The following demonstrates how to convert preEv to SysTime by opCast implicitly and by sys_time explicitly: import std.stdio; import std.conv; import std.datetime; struct preEv { string edate; //010112 string etime; //00:00:00 string etext; // SysTime opCast(T : SysTime)() const { return SysTime(DateTime( Clock.currTime.year, to!int(this.edate[2..4]), to!int(this.edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8]))); } SysTime sys_time() const property { return to!SysTime(this); } } void main() { auto pe = preEv("010312", "15:53:00", "The event"); // Explicit conversion auto st0 = to!SysTime(pe); writeln(st0); // Casting auto st1 = cast(SysTime)(pe); writeln(st1); // As a property auto st2 = pe.sys_time; writeln(st2); } If you think that you need to cache SysTime in the object itself, you can do that for example in opCast. On the other hand, if all you need to store is SysTime and etext, then you need to create SysTime in the constructor: import std.stdio; import std.conv; import std.datetime; struct preEv { SysTime time; string etext; this (string edate, string etime, string etext) { this.time = SysTime(DateTime( Clock.currTime.year, to!int(edate[2..4]), to!int(edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8]))); this.etext = etext; } } void main() { auto pe = preEv("010312", "15:53:00", "The event"); writeln(pe.time); } Ali
Mar 01 2012
On Thursday, March 01, 2012 16:00:09 Ali Çehreli wrote:On 03/01/2012 03:46 PM, albatroz wrote:You know, you can create a TimeOfDay from "15:53:00" with TimeOfDay.fromISOExtString. That won't work with the date, since it's not in either the ISO or ISO Extended format, but it would work for the time. I'd also point out that currTime isn't a property (since it takes an optional TimeZone argument), so you really should be using parens when you call it. Otherwise, once property enforcement is enabled, your code won't compile. Also, you should use std.conv.to, not a cast, when converting, since std.conv.to now supports calling user-defined opCasts, and there's less risk of screwing up the cast if you use std.conv.to. So, defining an opCast is fine, but it should probably be used with std.conv.to rather than directly. - Jonathan M DavisHi Ali, just tring to define a type that holds this information. It was just an attempt to create a type DateTime with the values from the known strings, I thought it was possible to create the definition directly in the Struct, with no need for an external function. edate and etime are strings that I will read in to the struct, but for operations with time and dates I need to create/define a DateTime type.From that description, it looks like you can hold edate etc. as members and produce SysTime as needed. The following demonstrates how to convert preEv to SysTime by opCast implicitly and by sys_time explicitly: import std.stdio; import std.conv; import std.datetime; struct preEv { string edate; //010112 string etime; //00:00:00 string etext; // SysTime opCast(T : SysTime)() const { return SysTime(DateTime( Clock.currTime.year, to!int(this.edate[2..4]), to!int(this.edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8]))); } SysTime sys_time() const property { return to!SysTime(this); } } void main() { auto pe = preEv("010312", "15:53:00", "The event"); // Explicit conversion auto st0 = to!SysTime(pe); writeln(st0); // Casting auto st1 = cast(SysTime)(pe); writeln(st1); // As a property auto st2 = pe.sys_time; writeln(st2); } If you think that you need to cache SysTime in the object itself, you can do that for example in opCast. On the other hand, if all you need to store is SysTime and etext, then you need to create SysTime in the constructor: import std.stdio; import std.conv; import std.datetime; struct preEv { SysTime time; string etext; this (string edate, string etime, string etext) { this.time = SysTime(DateTime( Clock.currTime.year, to!int(edate[2..4]), to!int(edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8]))); this.etext = etext; } } void main() { auto pe = preEv("010312", "15:53:00", "The event"); writeln(pe.time); }
Mar 01 2012
Hi Ali, only today I had the time to implement your suggestion it's working now has expected. Thank you for your patience, also thank you for the work translating such a good D book to English. On Friday, 2 March 2012 at 00:00:10 UTC, Ali Çehreli wrote:On 03/01/2012 03:46 PM, albatroz wrote:Hi Ali, just tring to define a type that holds thisinformation. It wasjust an attempt to create a type DateTime with the valuesfrom the knownstrings, I thought it was possible to create the definitiondirectly inthe Struct, with no need for an external function. edate and etime are strings that I will read in to thestruct, but foroperations with time and dates I need to create/define aDateTime type. From that description, it looks like you can hold edate etc. as members and produce SysTime as needed. The following demonstrates how to convert preEv to SysTime by opCast implicitly and by sys_time explicitly: import std.stdio; import std.conv; import std.datetime; struct preEv { string edate; //010112 string etime; //00:00:00 string etext; // SysTime opCast(T : SysTime)() const { return SysTime(DateTime( Clock.currTime.year, to!int(this.edate[2..4]), to!int(this.edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8]))); } SysTime sys_time() const property { return to!SysTime(this); } } void main() { auto pe = preEv("010312", "15:53:00", "The event"); // Explicit conversion auto st0 = to!SysTime(pe); writeln(st0); // Casting auto st1 = cast(SysTime)(pe); writeln(st1); // As a property auto st2 = pe.sys_time; writeln(st2); } If you think that you need to cache SysTime in the object itself, you can do that for example in opCast. On the other hand, if all you need to store is SysTime and etext, then you need to create SysTime in the constructor: import std.stdio; import std.conv; import std.datetime; struct preEv { SysTime time; string etext; this (string edate, string etime, string etext) { this.time = SysTime(DateTime( Clock.currTime.year, to!int(edate[2..4]), to!int(edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8]))); this.etext = etext; } } void main() { auto pe = preEv("010312", "15:53:00", "The event"); writeln(pe.time); } Ali
Mar 06 2012
On Thursday, March 01, 2012 15:15:00 albatroz wrote:Hi, I have defined this struct struct preEv { string edate; //010112 string etime; //00:00:00 string etext; // SysTime esystime; this (this) { SysTime esystime = SysTime(DateTime( Clock.currTime.year, to!int(this.edate[2..4]), to!int(this.edate[0..2]), to!int(etime[0..2]), to!int(etime[3..5]), to!int(etime[6..8]))); } } If I write to the sctruct and then print it I'm able to see the SysTime variable with a value. writeln(preEv) //previousEvents("140212", "05:13:26", "9 140212 05:13:26 d", "2012-Feb-14 05:13:26") but if trying to get the value from the SysTime variable I get a Segmentation fault. Trying to read any other variable inside this struct will not be a problem. writeln (preEv.esystime.day) // will compile but segfaults On DMD32 D Compiler v2.058 Any correct way to do this?A default-initialized SysTime is useless. It hasn't been properly initialized. SysTime contains a time zone object, which is a class and must be initialized at runtime (so directly initializing it won't work), and that object is null in SysTime.init (and it can't be anything else, because you can't construct a class at compile and have it persist to runtime). You need to actually initialize a SysTime before using it. So, using the init value of struct which has a SysTime as a member probably isn't a great idea. - Jonathan M Davis
Mar 01 2012