How to set (or correct for) timezone & DST in c (time.h functions) and DOS

强颜欢笑 提交于 2019-12-12 02:28:43

问题


I have a computer running DOS (freeDos 1.1) and plain C (compiled with Borland 5.0) with time.h. When I set the computer time using BIOS or the DATE and TIME DOS commands, there is no information about time zone. I set the time to my current time 10:25 AM.

My C program does this...

char timeString[80];
time_t timeT = time(NULL);
strftime(timeString, sizeof(timeString), "%a %Y-%m-%d %H:%M:%S %Z", localtime(&timeT));
printf("%s\n", timeString);

when I run the code I get the correct current time but with a "EST" time zone at the end as called by the %Z formatter.

Mon 2017-03-13 10:25:36 EST

The returned time_t value from time(NULL) is 1489418736.
This mathematically breaks down to 47 years, 83 days, 15 hours, 25 minutes, 36 seconds
Clearly time.h is implementing some time zone information here, adding 5 hours to my current time.

Moving over to javascript which receives the time_t value

new Date(1489418736 * 1000)

Mon Mar 13 2017 08:25:36 GMT-0700 (Pacific Daylight Time)

It seems there is some combination of time zone (EST vs PST vs GMT) and daylight savings time (which might account for the extra hour?) at play here. How can I affect the time zone and DST settings of the machine, operating system, or C library representation, to get the most useful time representation whether that be local or GMT?


回答1:


It's been many years, but I think there's a DOS environment variable that C looks for to determine the timezone. C may default to EST if it doesn't find the environment variable. I can't speak to the javascript aspects of the question.




回答2:


Concerning daylight issues, code is going to have troubles. In US, "my current time 10:25 AM should have been "Mon 2017-03-13 10:25:36 EDT" (EDT vs EST). The quaint TurboC code is certainly going to have troubles with the evolved DST rules that have differed over the decades.

IMO, any use of TurboC localtime(), mktime(), struct tm.isdst field and _daylight will all yield unsatisfactory results concerning daylight savings time and likely be an endless source of timezone issues. Either use a modern compiler/library or import/roll your own (ugh) timezone/daylight routines.

Alternative, stick to time_t and universal time - no local time




回答3:


DOS (including FreeDOS) has no notion of time zones. These OSes were designed with a simple end user in mind, not database design, mission critical apps, timestamp logging, the PC being in other timezones etc. In the end, the designers of these OSes took the path of least resistance. Everything was in the user's local time.

When C compilers started being written to conform to the Standard C API, there was a problem with implementing gmtime on DOS. DOS users set their PC to local time, not UTC. Unfortunately, you can't reliably convert a local time to UTC because of DST issues (you can reliably convert UTC to any local time), but the developers wanted a solution. They chose to ignore the issues that may arise with converting local time to UTC and allowed you to set the TZ environment variable to specify the conversion from local time to UTC.

In the absence of the TZ being set libraries defaulted to a timezone which often happened to be EST, which is the case with the Borland compilers. That is why you see EST being returned as the timezone by localtime.

Before running your application (preferably you set it in autoexec.bat at boot) you can use the set TZ= command to specify the conversion from local time to UTC. A good article on syntax of the TZ variable can be found here:

set TZ=tzn[+|-]hh[:mm[:ss] ][dzn]

TZN is the 3 letter time zone identifier for standard local time, and DZN is the 3 letter identifier for daylight savings time. TZN and DZN are used for display purposes. If DZN is omitted then this flags that daylight savings time doesn't apply to your time zone. The most important part is the offset (+/-) which specifies the amount of time to be added or subtracted from standard local time to convert it to UTC.

As an example, I'm in Mountain Standard Time (MST) and daylight savings time applies (MDT). MST is 7 hours behind UTC so 7 has to be added to my standard local time to get UTC. I'd set my timezone this way:

set TZ=MST7MDT

If I was in Newfoundland where standard time (NST) is 3.5 hours behind UTC and daylight savings time applies then I could use:

set TZ=NST3:30NDT

If I was in Saskatchewan, Canada that uses Central Standard Time (CST is 6 hours behind UTC) where daylight saving time doesn't apply then I'd use:

set TZ=CST6

My Recommendation - Use UTC in DOS

I have personally found in embedded systems where the OS isn't time zone aware, that it is easier to set the system clock to UTC instead of local time. You then write software to convert UTC to local time based on some software configuration if need be. This has the advantage that you can write the rules for DST. The rules for DST built into the Borland libraries no longer apply a generation later. Using UTC is also useful for timestamping event logs since you can express unambiguous times. In this situation I use:

set TZ=UTC0

which effectively makes local time the same as UTC.


DST Differences Between Products

At the time most of the Borland products were developed the rule employed for DST was for the US market. From 1987 through 2006 DST ran from the first Sunday of April to the last Sunday of October. After 2006 it was changed in the US to run from the second Sunday in March to the first Sunday in November.

The reason Borland C++ 5 (releases issued between 1996-1997) showed EST (and not EDT) was because from its perspective DST in 2017 didn't start until Sunday April 2nd, 2017 (first Sunday of April), so it still believed Monday March 13th, 2017 was still on Standard Time. The environment in which your Javascript ran is likely aware (based on modern underlying Time Zone databases and rules) that in 2017 DST came into effect on March 12th, 2017 (second Sunday in March) so it showed Monday March 13th, 2017 in Daylight Time (PDT). I will assume that Pacific Time was used because the system running the Javascript was told you are in a Pacific Time Zone that observes DST.



来源:https://stackoverflow.com/questions/42770184/how-to-set-or-correct-for-timezone-dst-in-c-time-h-functions-and-dos

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!