Skip to content

Instantly share code, notes, and snippets.

@dreamer
Created March 25, 2020 17:51
Show Gist options
  • Save dreamer/e95b5ef134926e692d4edb4ddd1d719c to your computer and use it in GitHub Desktop.
Save dreamer/e95b5ef134926e692d4edb4ddd1d719c to your computer and use it in GitHub Desktop.
#include <cstdint>
#include <cstdio>
#include <ctime>
#include <list>
using namespace std;
/*
MS-DOS date and MS-DOS time are data formats associated with MS-DOS.
They are used in some file formats from the MS-DOS era. Each is a
16-bit integer.
MS-DOS date represents a day in the range 1980 to 2099 (or maybe 2107,
but dates after 2099 aren't always correctly handled).
MS-DOS time represents a 2-second interval within some day. The time
is usually expected to be in "local time", and there is no indication
of the time zone. This makes it fairly useless in the internet age.
http://fileformats.archiveteam.org/wiki/MS-DOS_date/time
*/
tm dos_to_local_datetime(const uint16_t sec_count, const uint16_t day_count) {
tm tim = { 0 };
tim.tm_sec = (sec_count & 0x1f) * 2;
tim.tm_min = (sec_count >> 5) & 0x3f;
tim.tm_hour = (sec_count >> 11) & 0x1f;
tim.tm_mday = day_count & 0x1f;
tim.tm_mon = ((day_count >> 5) & 0x0f) - 1;
tim.tm_year = (day_count >> 9) + 1980 - 1900;
tim.tm_isdst = -1;
// serialize time
mktime(&tim);
return tim;
}
const char * day_to_str(uint16_t d)
{
switch (d) {
case 0: return "1980-01-01";
case 1: return "1980-01-02";
case 365: return "1980-12-31";
case 3653: return "1990-01-01";
case 7305: return "2000-01-01";
case 14694: return "2020-03-25";
case 43465: return "2099-01-01";
case 46386: return "2107-01-01";
case 65535: return "2159-06-06";
default: return "???";
}
}
int main()
{
std::list<uint16_t> seconds = { 0, 1, 29, 30, 31, 21599, 21600, 21601, 43199, 43200, 43201, 65535 };
std::list<uint16_t> days = { 0, 1, 365, 3653, 7305, 14694, 43465, 46386, 65535 };
char time_desc[100] = {};
for (const auto second : seconds) {
for (const auto day : days) {
const tm tim = dos_to_local_datetime(second, day);
strftime(time_desc, sizeof(time_desc), "%F", &tim);
printf("%6d, %6d | %10s | %10s\n",
second, day,
day_to_str(day),
time_desc);
}
}
return 0;
}
#include <cstdint>
#include <cstdio>
#include <ctime>
#include <list>
using namespace std;
/*
MS-DOS date and MS-DOS time are data formats associated with MS-DOS.
They are used in some file formats from the MS-DOS era. Each is a
16-bit integer.
MS-DOS date represents a day in the range 1980 to 2099 (or maybe 2107,
but dates after 2099 aren't always correctly handled).
MS-DOS time represents a 2-second interval within some day. The time
is usually expected to be in "local time", and there is no indication
of the time zone. This makes it fairly useless in the internet age.
http://fileformats.archiveteam.org/wiki/MS-DOS_date/time
*/
tm dos_to_local_datetime(const uint16_t sec_count, const uint16_t day_count) {
tm tim = { 0 };
tim.tm_sec = (sec_count & 0x1f) * 2;
tim.tm_min = (sec_count >> 5) & 0x3f;
tim.tm_hour = (sec_count >> 11) & 0x1f;
tim.tm_mday = day_count & 0x1f;
tim.tm_mon = ((day_count >> 5) & 0x0f) - 1;
tim.tm_year = (day_count >> 9) + 1980 - 1900;
tim.tm_isdst = -1;
// serialize time
mktime(&tim);
return tim;
}
const char * day_to_str(uint16_t d)
{
switch (d) {
case 0: return "1980-01-01";
case 1: return "1980-01-02";
case 365: return "1980-12-31";
case 3653: return "1990-01-01";
case 7305: return "2000-01-01";
case 14694: return "2020-03-25";
case 43465: return "2099-01-01";
case 46386: return "2107-01-01";
case 65535: return "2159-06-06";
default: return "???";
}
}
int main()
{
std::list<uint16_t> seconds = { 0, 1, 29, 30, 31, 21599, 21600, 21601, 43199, 43200, 43201, 65535 };
std::list<uint16_t> days = { 0, 1, 365, 3653, 7305, 14694, 43465, 46386, 65535 };
char time_desc[100] = {};
for (const auto second : seconds) {
for (const auto day : days) {
const tm tim = dos_to_local_datetime(second, day);
strftime(time_desc, sizeof(time_desc), "%F", &tim);
printf("%6d, %6d | %10s | %10s\n",
second, day,
day_to_str(day),
time_desc);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment