2009-03-20 5 views
6

사양에 액세스 할 수없는 이전 데이터 형식에 대한 DateTime 구조가 있습니다. 데이터의 날짜 시간을 나타내는 필드가 있지만 인식 할 수있는 형식이 아닙니다. 그것은 하루에 20 씩 증가하는 32 비트 정수로 저장되는 것으로 보입니다. 누구도 이런 식으로 달렸어?날짜/시간 형식은 무엇입니까?

EDIT :

예 : 80 = 34 E3 1,088,631,936 12월 40 00 00 00 00 HEX = 2007년 9월 7일

EDIT :

첫째, 지연 미안. 나는 주말 내내 일을하기를 바랬지 만 할 수 없었다.

둘째로,이 날짜 형식은 내가 처음 생각한 것보다 더 이상합니다. 날짜가 증가하는 속도로 변하지 않기 때문에 그것은 일종의 지수 또는 로그 방법 인 것으로 보입니다.

셋째,이 값을 해석 할 때 사용하지 않는 앱은 날짜 부분 만 표시하므로 시간 부분이 무엇인지 알 수 없습니다.

데이터 예 : (16 진수 값은 날짜, 빅 엔디안 MM/DD/YYYY)

= 0x40000000과 01/01/1900
0x40010000 = 01/01/1900
0x40020000 = 01/01/1900
0x40030000 = 01/01/1900
0x40040000 = 01/01/1900
0x40050000 = 01/01/1900
0x40060000 = 01/01/1900
0x40070000 = 01/01/1900
백45경1천5백15조5백36억9천1백36만3천2백10 0x40080000 = 1900년 1월 2일
0x40090000 = 1900년 1월 2일
0x400A0000 = 1900년 1월 2일
0x400B0000 = 1900년 1월 2일
0x400C0000 = 1900년 1월 2일
0x400D0000 = 01/02/1900
0x400E0000 = 1900년 1월 2일
0x400F0000 = 1900년 1월 2일
0x40100000 = 1900년 1월 3일
0x40110000 = 1900년 1월 3일
0x40120000 = 1900년 1월 3일
0x40130000 = 01/03/1900,453,210 0x40140000 = 1900년 1월 4일
0x40150000 = 1900년 1월 4일
0x40160000 = 1900년 1월 4일
0x40170000 = 1900년 1월 4일
0x40180000 = 1900년 1월 5일
0x40190000 = 01/05/1900 =
0x401A0000 1900년 1월 5일
0x401B0000 = 1900년 1월 5일
0x401C0000 = 1900년 1월 6일
0x401D0000 = 1900년 1월 6일
0x401E0000 = 1900년 1월 6일
0x401F0000 = 01/06/1900 0 123, 0x40200000 = 1900년 1월 7일
0x40210000 = 1900년 1월 7일
0x40220000 = 1900년 1월 8일
0x40230000 = 1900년 1월 8일
....
0x40800000 = 05/26/1,901
0x40810000 = 1901년 6월 27일
0x40820000 = 1901년 7월 29일
....
0x40D00000 = 1944년 11월 8일
0x40D10000 = 1947년 8월 29일

EDIT : 마침내 알아 냈습니다.하지만 이미 현상금에 대한 점수를 포기했기 때문에 아무에게도 기회를주기를 원한다면 해결책을 취하지 않을 것입니다.

현재로서는 시간 구성 요소가 없으며 날짜를 저장하기위한 용도로만 사용됩니다.

+0

데이터 형식, 관련 프로그램의 이름 같은? –

+0

아니면 예제가 포함 되었습니까? –

+0

죄송합니다. 귀하의 예가 제게 의미가 없습니다. "DEC ="와 "OCT ="가 무슨 뜻입니까? 왜 그들은 서로 다른 유형의 "동등"합니까? –

답변

7

정수가 아니며 32 비트 부동 소수점 숫자입니다. 아직 형식을 다듬지는 않았지만 IEEE가 아닙니다.

편집 : 알겠습니다.1 비트 부호, 0x3ff 오프셋을 갖는 11 비트 지수, 및 왼쪽에 함축 된 비트를 갖는 20 비트 가수. 이 0x40000000과 = 2.0 산출

double offset = pow(2, (i >> 20) - 0x3ff) * (((i & 0xfffff) + 0x100000)/(double) 0x100000); 

, 그래서 시작 날짜는 1899년 12월 30일을해야합니다 : C에서, 단지 양수 가정.

다시 편집 : 내 대답을 받아 들일만큼 친절했기 때문에 속도에 대해 염려스러워 보였으므로 조금 더 상세하게 조정해야한다고 생각했습니다. 실수의 소수 부분은 필요하지 않으므로 비트 연산 만 사용하여 곧바로 정수로 변환 할 수 있습니다. 이번에 Python에서는 테스트 결과를 완성한다. 더 나은 가독성을 위해 몇 가지 중간 값을 포함했습니다. 음수가 제한되지 않은 이외에도이 버전은 지수가 19 이상이되면 문제가 발생할 수 있지만 3335 년까지는 계속 좋을 것입니다.

>>> def IntFromReal32(i): 
     exponent = (i >> 20) - 0x3ff 
     mantissa = (i & 0xfffff) + 0x100000 
     return mantissa >> (20 - exponent) 

>>> testdata = range(0x40000000,0x40240000,0x10000) + range(0x40800000,0x40830000,0x10000) + [1088631936] 
>>> from datetime import date,timedelta 
>>> for i in testdata: 
     print "0x%08x" % i, date(1899,12,30) + timedelta(IntFromReal32(i)) 


0x40000000 1900-01-01 
0x40010000 1900-01-01 
0x40020000 1900-01-01 
0x40030000 1900-01-01 
0x40040000 1900-01-01 
0x40050000 1900-01-01 
0x40060000 1900-01-01 
0x40070000 1900-01-01 
0x40080000 1900-01-02 
0x40090000 1900-01-02 
0x400a0000 1900-01-02 
0x400b0000 1900-01-02 
0x400c0000 1900-01-02 
0x400d0000 1900-01-02 
0x400e0000 1900-01-02 
0x400f0000 1900-01-02 
0x40100000 1900-01-03 
0x40110000 1900-01-03 
0x40120000 1900-01-03 
0x40130000 1900-01-03 
0x40140000 1900-01-04 
0x40150000 1900-01-04 
0x40160000 1900-01-04 
0x40170000 1900-01-04 
0x40180000 1900-01-05 
0x40190000 1900-01-05 
0x401a0000 1900-01-05 
0x401b0000 1900-01-05 
0x401c0000 1900-01-06 
0x401d0000 1900-01-06 
0x401e0000 1900-01-06 
0x401f0000 1900-01-06 
0x40200000 1900-01-07 
0x40210000 1900-01-07 
0x40220000 1900-01-08 
0x40230000 1900-01-08 
0x40800000 1901-05-26 
0x40810000 1901-06-27 
0x40820000 1901-07-29 
0x40e33480 2007-09-07 
+0

0x40220000 -> 01/06/1900을주지 않습니까? – mbeckish

+0

아니요, 맞습니다. 0x40220000 = 9.0, 12/30/1899에 12/39/1899를 더합니다. 31 일을 빼고 그 달을 나르면 1900 년 1 월 8 일에 떠난다. –

+0

잘 했어. 당신의 대답은 옳을뿐만 아니라, 내가했던 방식보다 훨씬 빠릅니다. 현상금을 가져라. – Kevin

3

값이 09/07/2007에 해당합니까?

1088631936은 Linux (et al) 제로 날짜 이후의 초 수 : 01/01/1970 00:00:00부터 06/30/2004 21:45:36까지입니다.

평소 0 일 이후의 값이라고 생각하는 것이 합리적입니다.

편집 : 정답이 아닐 가능성이 매우 높습니다. 그것은 단지 하나의 접근법 (유효한 것)이지만 더 많은 정보가 필요하다고 생각합니다 (주석 참조). 다른 사람이 그 질문에 대답하거나 아이디어를 줄 수 있기를 바라며 질문을 앞쪽으로 가져 오도록 편집하십시오. 나 : 공평하고, 호기심을 자극하고 정신을 공유하십시오 : D

1

나는 vmarquez가 가깝다고 말하고 싶습니다. 그들은 16 진수에 여기

In [8]: time.strftime("%s", (2009, 3, 21, 1, 1, 0, 0,0,0)) 
Out[8]: '1237590060' 

In [9]: time.strftime("%s", (2009, 3, 22, 1, 1, 0, 0,0,0)) 
Out[9]: '1237676460' 

그리고 :

In [10]: print("%0x %0x" % (1237590060, 1237676460)) 
49c4202c 49c571ac 

당신은 처음 5 자리 걸릴 경우 다음

날짜 2009년 3월 21일 및 유닉스 epochtime로 2009년 3월 22일 있습니다 , 성장은 21입니다. 어느 형식과 일치합니까?

+0

감사합니다. Pasi. 수학은 간단하고 깨끗하며 설명에 매우 가깝습니다. "날마다 20 씩 증가"가 정확한지 아니면 "20 일 꼴"과 같은지 궁금합니다. 어쨌든, 우리는 신기원 문제 (0 날짜는 무엇입니까?)가 남아 있습니다. – vmarquez

1

일부 컨텍스트가 유용합니다. 데이터 파일이 문자 그대로 또는 적어도 비 유적으로이 파일처럼 보이면 vmarquez가 돈이됩니다.

http://www.slac.stanford.edu/comp/net/bandwidth-tests/eventanalysis/all_100days_sep04/node1.niit.pk

해당 참조 가능한 대역폭 추정 툴 (ABwE)에 의해 생성 된 데이터 인 - 호기심 항목이 실제로 상황뿐만 아니라 그 1,088,631,936 값을 포함한다는 것이다. 예 :

date  time  abw  xtr dbcap avabw avxtr avdbcap  rtt timestamp 
06/30/04 14:43:48 1.000 0.000 1.100 1.042 0.003 1.095 384.387 1088631828 
06/30/04 14:45:36 1.100 0.000 1.100 1.051 0.003 1.096 376.408 1088631936 
06/30/04 14:47:23 1.000 0.000 1.100 1.043 0.003 1.097 375.196 1088632043 
은 제안 된 21:45:36 시간 값에서 7 시간 오프셋 된 것으로 보입니다. (아마도 스탠포드 지역, 일광 절약 시간제로 실행 중일 것입니다.)

+0

이제 멋진 곳입니다! +1 – vmarquez

0

우리는 프로그램에서 8 자리 중 2 자리를 사용하는 방법을 보여 주었기 때문에 다른 6 자리는 무시됩니다 프로그램은 다른 숫자로 원하는 모든 것을 수행 할 수 있습니다).

따라서 입력 형식은 40mn0000 입니다. 여기서 m 및 n은 16 진수 2 자리입니다.

그리고, 출력은 다음 01/01/1900 + 층 ((2^(m + 1) -2) + N * 2^(m-3)) 일

설명 : 각 예에서

  1. 는 N을 1만큼 증가시키는 것은 2^(m-3)에 의해 일의 수를 증가 알.
  2. n이 F에서 0으로 갈 때마다 m이 증가한다는 점에 유의하십시오.

이 두 규칙을 사용하여 숫자를 가지고 놀면 위의 수식이됩니다. (출력에 소수 자릿수가 표시되지 않기 때문에 추가 된 층은 제외).

나는 n은 그러나 한 두 자리 16 진수의 H.으로, 나는 그 방정식은 훨씬 더 추악한 할 것이라고 생각 당신은 두 개의 별도의 진수 변수 m을 대체하여이 문제를 다시 수도있을 것 같군요.

+0

축하합니다. 수식 확인. – vmarquez

+0

내가받은 첫 번째 예를 놓쳤습니다. 0x40E33480 = 09/07/2007 – Kevin

관련 문제