
Hello list, Apologies for the cross-posting, this originally went to the boost-users list but it got no responses, and then I also realized it was actually more appropriate here. Suppose I have a cross-platform agent that communicates with a server. Agent from platform X sends a message to the server which contains a date/time. Server sends a message to another agent running platform Y with the same date/time. In practice X/Y are always either windows/linux or linux/windows. The server always tells the agent which platform's native format the time is represented in, so there should be no problem. Ideally I'd like to write the following code: ptime time; if (msg.is_from_windows()) { time = from_ftime<ptime>(msg.time()); } else { time = from_time_t(msg.time()); } But this doesn't work because from_ftime<> is not defined on linux. If from_ftime<> is already templated on the FILETIME type, is there any reason it needs to be #ifdef'd out on non-windows platforms? I mean, a FILETIME is really just a uint64, can't the templated function also just operate on a boost::uint64_t? Zach

Zachary Turner wrote:
Hello list,
Apologies for the cross-posting, this originally went to the boost-users list but it got no responses, and then I also realized it was actually more appropriate here.
Suppose I have a cross-platform agent that communicates with a server. Agent from platform X sends a message to the server which contains a date/time. Server sends a message to another agent running platform Y with the same date/time. In practice X/Y are always either windows/linux or linux/windows. The server always tells the agent which platform's native format the time is represented in, so there should be no problem. Ideally I'd like to write the following code:
ptime time; if (msg.is_from_windows()) { time = from_ftime<ptime>(msg.time()); } else { time = from_time_t(msg.time()); }
But this doesn't work because from_ftime<> is not defined on linux. If from_ftime<> is already templated on the FILETIME type, is there any reason it needs to be #ifdef'd out on non-windows platforms? I mean, a FILETIME is really just a uint64, can't the templated function also just operate on a boost::uint64_t?
Actually, FILETIME is a structure, the function just optimises its operation by converting it to uint64_t internally, which may not be valid on Linux. Obviously, this structure is not available on Linux, so there's no way you can acquire it from OS. The from_ftime function (and all other facilities it uses) are targeted for Windows platform and operate on FILETIME, not on some opaque uint64_t. FILETIME has additional value semantics, such as the base date and resolution. These semantics are not described for Linux. FWIW, it looks strange to me that you use the same field in the protocol to pass times in different formats depending on the OS. IMHO, the best way to go is to make the protocol OS-independent.

On Sun, Nov 1, 2009 at 3:42 AM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
Actually, FILETIME is a structure, the function just optimises its operation by converting it to uint64_t internally, which may not be valid on Linux. Obviously, this structure is not available on Linux, so there's no way you can acquire it from OS.
The from_ftime function (and all other facilities it uses) are targeted for Windows platform and operate on FILETIME, not on some opaque uint64_t. FILETIME has additional value semantics, such as the base date and resolution. These semantics are not described for Linux.
I agree, but the point is that semantically a FILETIME is defined as "an opaque structure representing the number of 100-nanosecond intervals since January 1, 1601". Integer types are perfectly capable of representing exactly the same semantic definition, so why not? I don't think it even requires any code changes except to remove a single #ifdef in the date_time header files.

Zachary Turner wrote:
On Sun, Nov 1, 2009 at 3:42 AM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
Actually, FILETIME is a structure, the function just optimises its operation by converting it to uint64_t internally, which may not be valid on Linux. Obviously, this structure is not available on Linux, so there's no way you can acquire it from OS.
The from_ftime function (and all other facilities it uses) are targeted for Windows platform and operate on FILETIME, not on some opaque uint64_t. FILETIME has additional value semantics, such as the base date and resolution. These semantics are not described for Linux.
I agree, but the point is that semantically a FILETIME is defined as "an opaque structure representing the number of 100-nanosecond intervals since January 1, 1601". Integer types are perfectly capable of representing exactly the same semantic definition, so why not? I don't think it even requires any code changes except to remove a single #ifdef in the date_time header files.
It does. At least byte order issues should be taken into account. Anyway, I don't think that bringing Windows-specific code to other platforms is a good idea. If you want cross-platform code, use cross-platform types, such as time_t, ptime or local_time.

On Sun, Nov 1, 2009 at 12:58 PM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
Zachary Turner wrote:
On Sun, Nov 1, 2009 at 3:42 AM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
Actually, FILETIME is a structure, the function just optimises its
operation by converting it to uint64_t internally, which may not be valid on Linux. Obviously, this structure is not available on Linux, so there's no way you can acquire it from OS.
for Windows platform and operate on FILETIME, not on some opaque uint64_t. FILETIME has additional value semantics, such as the base date and resolution. These semantics are not described for Linux.
I agree, but the point is that semantically a FILETIME is defined as "an opaque structure representing the number of 100-nanosecond intervals since January 1, 1601". Integer types are perfectly capable of representing exactly the same semantic definition, so why not? I don't think it even requires any code changes except to remove a single #ifdef in the date_time
The from_ftime function (and all other facilities it uses) are targeted header files.
It does. At least byte order issues should be taken into account.
Anyway, I don't think that bringing Windows-specific code to other platforms is a good idea. If you want cross-platform code, use cross-platform types, such as time_t, ptime or local_time.
That's just it, I'm trying to use ptime. A conversion has to exist somewhere, why shouldn't it exist in boost rather than me duplicating code for no particular benefit? If I decide that a unix epoch based time is going to be my "cross-platform network format" when I serialize / deserialize then I lose precision on Windows. If I decide that a windows epoch based time is going to be my cross platform network format, then I have to make an almost exact duplicate of the from_ftime function. Besides, my application does raw parsing of an NTFS filesystem. You can have NTFS filesystems on Linux. Usually the APIs abstract the fact that times are stored internally in the filesystem in FILETIME format, but that's no longer the case when you have raw access to the file systme.

Zachary Turner wrote:
Anyway, I don't think that bringing Windows-specific code to other platforms is a good idea. If you want cross-platform code, use cross-platform types, such as time_t, ptime or local_time.
That's just it, I'm trying to use ptime.
Then why not simply send ptime over the network?
A conversion has to exist somewhere, why shouldn't it exist in boost rather than me duplicating code for no particular benefit? If I decide that a unix epoch based time is going to be my "cross-platform network format" when I serialize / deserialize then I lose precision on Windows. If I decide that a windows epoch based time is going to be my cross platform network format, then I have to make an almost exact duplicate of the from_ftime function.
That choice is up to you. However, as I implied earlier, I see no point in using platform-dependent types in a cross-platform code, except for the lower-level wrappers around the native OS API.
Besides, my application does raw parsing of an NTFS filesystem. You can have NTFS filesystems on Linux. Usually the APIs abstract the fact that times are stored internally in the filesystem in FILETIME format, but that's no longer the case when you have raw access to the file systme.
I can't comment on that as I'm not aware of NTFS internals. I'm not the maintainer of Boost.DateTime, but this use case doesn't convince me as it looks too exotic to me.

On Mon, Nov 2, 2009 at 12:38 PM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
Zachary Turner wrote:
Anyway, I don't think that bringing Windows-specific code to other
platforms is a good idea. If you want cross-platform code, use cross-platform types, such as time_t, ptime or local_time.
That's just it, I'm trying to use ptime.
Then why not simply send ptime over the network?
Using what method? by sending the result of ptime::ticks()? If so, how do I reconstruct a ptime from the result of this? Also, the server that this information is being sent to is written in Java, and it needs to be able to understand whatever is sent across (i.e. extract day/month/year/etc information)

Zachary Turner wrote:
On Mon, Nov 2, 2009 at 12:38 PM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
Zachary Turner wrote:
Anyway, I don't think that bringing Windows-specific code to other
platforms is a good idea. If you want cross-platform code, use cross-platform types, such as time_t, ptime or local_time.
That's just it, I'm trying to use ptime. Then why not simply send ptime over the network?
Using what method? by sending the result of ptime::ticks()? If so, how do I reconstruct a ptime from the result of this?
IIRC, currently you have to separately serialize date and time. The date is simply a number of days since the base date. The time has ticks() and ticks_per_second() or something like that. So there is no problem to reconstruct the correct ptime on another machine, even with different time resolution capability.
Also, the server that this information is being sent to is written in Java, and it needs to be able to understand whatever is sent across (i.e. extract day/month/year/etc information)
I don't see a problem with it. Anyway, I'm more inclined to improve ptime portability instead of porting FILETIME.

Zachary Turner wrote:
On Sun, Nov 1, 2009 at 12:58 PM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
Zachary Turner wrote:
On Sun, Nov 1, 2009 at 3:42 AM, Andrey Semashev <andrey.semashev@gmail.com>wrote:
Actually, FILETIME is a structure, the function just optimises its
operation by converting it to uint64_t internally, which may not be valid on Linux. Obviously, this structure is not available on Linux, so there's no way you can acquire it from OS.
for Windows platform and operate on FILETIME, not on some opaque uint64_t. FILETIME has additional value semantics, such as the base date and resolution. These semantics are not described for Linux.
I agree, but the point is that semantically a FILETIME is defined as "an opaque structure representing the number of 100-nanosecond intervals since January 1, 1601". Integer types are perfectly capable of representing exactly the same semantic definition, so why not? I don't think it even requires any code changes except to remove a single #ifdef in the date_time
The from_ftime function (and all other facilities it uses) are targeted header files.
It does. At least byte order issues should be taken into account.
Anyway, I don't think that bringing Windows-specific code to other platforms is a good idea. If you want cross-platform code, use cross-platform types, such as time_t, ptime or local_time.
That's just it, I'm trying to use ptime. A conversion has to exist somewhere, why shouldn't it exist in boost rather than me duplicating code for no particular benefit? If I decide that a unix epoch based time is going to be my "cross-platform network format" when I serialize / deserialize then I lose precision on Windows.
IUC you won't lose _precision_. The resolution of the timestamp might be in the order of 100s of nanoseconds, but the precision is somewhere in the order of tens of milliseconds under WinNT+.
If I decide that a windows epoch based time is going to be my cross platform network format, then I have to make an almost exact duplicate of the from_ftime function.
As Andrey suggested; if you're developing a cross-platform protocol, don't tie it to one of the platform's native format. Use a platform-neutral format. Why not just serialize the date/time as a sequence of integers (year,month,day,hour,min,sec,nanosecs) with a defined byte order, that represents the time (as GMT/UTC)?
Besides, my application does raw parsing of an NTFS filesystem. You can have NTFS filesystems on Linux. Usually the APIs abstract the fact that times are stored internally in the filesystem in FILETIME format, but that's no longer the case when you have raw access to the file systme.
Depending on how you actually use these timestamps, there could be a valid reason for using FILETIME as the wire format. Best regards, Johan Nilsson
participants (3)
-
Andrey Semashev
-
Johan Nilsson
-
Zachary Turner