Is this a timestamp?

I'm not sure where to post this, but here goes:

I'm trying to understand how a binary file (.DAT) generally works. I'm using a hex editor do this. I understand most of the file, however I'm stuck with this timestamp problem. I'm 100% sure that a part of this hex is the actual timestamp:

e1 27 17 6f e6 69 c0 00 e1 27 18 65 10 84 ef

On screen, it outputs: 9/4/2009 5:22

Note: it's DD/MM/YYYY formatted.

I've tried conversions (hex->decimal->timestamp) but no luck so far.. none of the results match the one that I've just posted above.

Any idea? Do I need to swap certain bytes or...? Or are 100% sure that this is the actual timestamp?

Thanks in advance.
Either a) the date is in UNIX format, which is an integer that counts the seconds since 19700101T000000Z, or b) the bits in the date are packed, such that only the minimum amount of space is used for each field (i.e. 5 bits for the day of the month, 4 for the month, etc.).
Could you tell us what kind of dat file this string of hex digits came from? Does the dat file have any encryption? Is there a particular program that uses this? etc. Just anything that could help us help.
These are 15 bytes, so it's likely that one byte is missing or that you have too many.
4 and 8 bytes are common for a timestamp. 16 bytes is uncommon, but not unthinkable.
The file is unencrypted. And yes, the line is 16 bytes. The first byte is just '00'.

0x2d10: 00 00 00 32 00 00 00 01 00 01 10 00 00 00 00 00
0x2d20: 00 e1 27 17 6f e6 69 c0 00 e1 27 18 65 10 84 ef
0x2d30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

The '32' byte (0x2d13) is an identify for the next offset. On screen, that identify and its timestamp are displayed.

This file is on Playstation 3, a system that uses the PCC architecture. So, yes, UNIX is probably used.

Thanks again!
It would be much easier if there was a second timestamp for comparison.
Last edited on
Definitely not UNIX time. That time in UNIX time is either 49DD85F8 or 49DE2EB8 (depending on whether 05:22 is AM or PM). Nothing in those strings looks even remotely like either number.
There's another timestamp with a different ID:

0x2B60: 00 00 00 2f 00 00 00 01 00 01 10 00 00 00 00 00
0x2B70: 00 e1 2b 9e df 79 66 80 00 e1 2b 9f db d9 7b 6e
0x2B80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

This one outputs 7/4/2009 22:02 (on screen).

I'm sure these strings are the timestamps. If I remove them out of the file, the timestamps don't display on screen.

Hmm, let's put these two strings (two timestamps) altogether and compare...

00 e1 27 17 6f e6 69 c0 00 e1 27 18 65 10 84 ef
00 e1 2b 9e df 79 66 80 00 e1 2b 9f db d9 7b 6e

Hmm...

Last edited on
Yeah, that helps. It shows that each of those are actually two 8-byte timestamps (modified, accessed, created...?).
When looking at one of these numbers in decimal form, it becomes clear that it must be the microseconds that have passed since Jan 1 of the year 1.

So that results in the following four timestamps, which seem about right (except the last two, but I assume you just posted the wrong date):
2009-04-09 05:22:55
2009-04-09 06:31:28
2009-06-05 20:38:34
2009-06-05 21:49:08
Thanks, Athar! Do you mind how exactly did you do that? What tool did you use? I'm a bit confused... Thanks again! Did you calcuate without the '00 e1 27' part ?

And yep, sorry! I posted the wrong date on the second timestamp.
Last edited on
Oh, so... 00 e1 27 17 6f e6 69 c0 = 63,374,851,375,000,000

I'm not quite sure how to convert that microseconds into a timestamp based on Jan 1 Year 1. The converters I know only use the Jan 1 Year 1970 format. :/
What time is that? I'm getting an error of 1h 26m 24s if it's 2009-04-09 05:22:55
((((2008*365.2425+31+28+31+8)*24+5)*60+22)*60+55)*1000000 = 63,374,846,191,000,000
If I'm correct... 9/4/2009 5:22 equals 63,374,851,375,000,000. Right?

I cannot confirm this though... I've tried converters but they give me wrong results..
helios wrote:
What time is that? I'm getting an error of 1h 26m 24s if it's 2009-04-09 05:22:55
((((2008*365.2425+31+28+31+8)*24+5)*60+22)*60+55)*1000000 = 63,374,846,191,000,000

That's because 2008*365.2425 results in a non-integer, so if you round up (in this case), you'll get the correct result.

Serady wrote:
If I'm correct... 9/4/2009 5:22 equals 63,374,851,375,000,000. Right?

Aye, that's right (+ the 55 seconds to split some cat hairs).

As for doing the conversion, see here:
http://en.wikipedia.org/wiki/Julian_day#Alternatives

You can get the "Rata Die" directly from the timestamp and convert it to the Julian Day Number.
Which can be then be used to figure out the date using the algorithm below:
http://en.wikipedia.org/wiki/Julian_day#Gregorian_calendar_from_Julian_day_number
Last edited on
Thanks for your reply, Athar. Much appreciated. One last thing, would you mind sharing your code? :)
If you want... however, not only is it very inefficient due to the naive counting loop, but it also behaves incorrectly at the last day of a leap year (and probably around February/March transitions as well).
You're better off implementing the algorithm on the Wikipedia site.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
//#include <stdfunc.hpp>
//#include <strfunc.hpp>
using namespace std;

static inline bool isLeapYear(int year)
{
  return year%4==0 && (year%100!=0 || year%400==0);
}

int main()
{
  int64_t secs=63379835348ll;
  int year=1;
  while (secs>=365*86400)secs-=(isLeapYear(year++)? 366 : 365)*86400;

  static const int daysPerMonth[]={31,28,31,30,31,30,31,31,30,31,30,31};
  int currentMonth=0;
  while (secs>=daysPerMonth[currentMonth]*86400)
  {
    int days=daysPerMonth[currentMonth++];
    if (currentMonth==2 && isLeapYear(year))days=29;
    secs-=86400*days;
  }
  currentMonth++;

  const int day=secs/86400+1;
  secs%=86400;

  const int hours=secs/3600;
  secs%=3600;
  const int minutes=secs/60;
  secs%=60;

  cout << year << "-" << leadingZeros(currentMonth,2) << "-" << leadingZeros(day,2) << " " << leadingZeros(hours,2) << ":" << leadingZeros(minutes,2) << ":" << leadingZeros(secs,2) << endl;
}
Last edited on
Topic archived. No new replies allowed.