Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Перевод даты и времени в секунды


Автор: Ivan_S 30.8.2004, 14:56
У кого нибудь есть функция перевода даты и времени в секунды и обратно.
можно на любом языке.
Необходимо перевести время в число секунд прошедшее до этого момента с 0:00:00 01.01.2000 и обратно.
Это число кокрас влезает в long

Автор: Domestic Cat 30.8.2004, 16:57
На Java пойдет? (извиняюсь что не C++, но вроде нужно на любом языке)
Код

import java.util.*;
public class Test
{
   public static void main(String[] ard)
   {
       Calendar calendar = Calendar.getInstance();
       calendar.set(2000, 0 /*January*/, 1, 0, 0, 0);
       long ms = calendar.getTimeInMillis();
       long diff = (System.currentTimeMillis() - ms) / 1000; // ms -> s
       System.out.println(diff);
   }
}

Автор: Олег М 31.8.2004, 05:40
Цитата(Ivan_S @ 30.8.2004, 17:56)
Необходимо перевести время в число секунд прошедшее до этого момента с 0:00:00 01.01.2000 и обратно.

Переводи в FILETIME, например SystemTimeToFileTime, там время хранится с точностью до 100 нс, не помню сколько это в секундах, вроде бы одна десятитысячная. Дели на 10000 и всё.

Автор: Ivan_S 31.8.2004, 09:02
Проблема в том, что я пишу программу под микросхему "ATMega8", в котором только голый C, даже не C++. И нет ни каких дополнительных функций для работы со временем и датой.
Программа должна считывать информацию с микросхемы DS1307, которая возвращает текущую дату и время в виде

......|.BIT7.|..........|..........|..........|..........|..........|..........|.BIT0...|
......-------------------------------------------------------------------------
00H|...CH..|......10.Seconds........|..............Seconds.................|..00-59
......-------------------------------------------------------------------------
......|....0....|......10.Minutes.........|..............Minutes..................|..00-59
......-------------------------------------------------------------------------
......|....0....|..12 /.|10 HR.|10.HR.|.................Hours..................|..1-12
......|..........|....24.|..A/P...|..........|.............................................|..00-23
......-------------------------------------------------------------------------
......|....0....|....0...|....0....|....0....|....0....|.............Day...............|..1-7
......-------------------------------------------------------------------------
......|....0....|....0...|.....10 Date....|..................Date...................|..01-28/29;..01-30;..01-31
......-------------------------------------------------------------------------
......|....0....|....0...|....0....|10.Mo|...................Month.................|..01-12
......-------------------------------------------------------------------------
......|...............10 Year................|..................Year...................|..00-99
......-------------------------------------------------------------------------

перевести это в long и вместе с другими замеренными параметрами записать во Flash память.

Функцию перевода в long я написал:

//----------------------------------------------------------------------------------------------------
#define CharData(_data, _pos) _data[_pos]
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
//----------------------------------------------------------------------------------------------------
uint MONTH[12]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
ulong getSec(const uchar *DateTime){
uint gYear=CharData(DateTime, 6);
gYear=(gYear&0x0F)+((gYear&0xF0)>>1)+((gYear&0xF0)>>3);
uint gMonth=CharData(DateTime, 5)&0x1F;
gMonth=(gMonth&0x0F)+((gMonth&0x10)>>1)+((gMonth&0x10)>>3);
uint gDate=CharData(DateTime, 4)&0x3F;
gDate=(gDate&0x0F)+((gDate&0x30)>>1)+((gDate&0x30)>>3);
uint gDay=gYear*365+((gYear+3)>>2);
gDay+=MONTH[gMonth-1]+((gMonth>2) ?!(gYear%4) :0);
gDay+=gDate-1;
uint gHours=CharData(DateTime, 2)&0x3F;
gHours=(gHours&0x0F)+((gHours&0x30)>>1)+((gHours&0x30)>>3);
uint gMinutes=CharData(DateTime, 1)&0x7F;
gMinutes=(gMinutes&0x0F)+((gMinutes&0x70)>>1)+((gMinutes&0x70)>>3);
ulong gSeconds=CharData(DateTime, 0)&0x7F;
gSeconds=(gSeconds&0x0F)+((gSeconds&0x70)>>1)+((gSeconds&0x70)>>3);
gSeconds=(ulong)gDay*86400+gHours*3600+gMinutes*60+gSeconds;
return gSeconds;
}
//----------------------------------------------------------------------------------------------------
, а обратно уже замаелся

Автор: Олег М 31.8.2004, 11:12
Ivan_S задача вроде халявная - опиши словами данные с микросхемы, а то так врубиться не могу.

Автор: Ivan_S 1.9.2004, 11:06
микросхема возвращает 8 байт:
00h - секунды
01h - минуты
02h - часы
03h - день недели
04h - дата
05h - месяц
06h - год
07h - системный байт

все значения имеют формат BCD (двоично-десятичный код).
младшие 4 бита - младшая цифра,
старшие 4 бита - старшая цифра.

Микросхема автоматически учитывает высокосный год.

необходимо перевести все значения часов в нормальный вид и подсчитать абсолютное число секунд от начала счетчика и обратно.

Автор: Олег М 1.9.2004, 13:44
Не так просто оказалось - вот что накидал - как работает не проверял, но общий смысл понятен
Код

inline int BSD2INT(char bcd) { return ((bcd) & 0x0F)+10*((bcd)>>4);}
inline char INT2BCD(int n) {return (n%10)  | ((n/10)<<4);}


char date[8];

long dt;
dt=BSD2INT(date[0]); //Кол-во секунд
dt+=BSD2INT(date[1])*60; //Кол-во секунд в минуте
dt+=BSD2INT(date[2])*60*60;//Кол-во секунд в часе
dt+=(BSD2INT(date[4])-1)*60*60*24; //Кол-во секунд в дне
dt+=(BSD2INT(date[5])-1)*60*60*24*Кол_во_дней_до_начала_месяца;
dt+=(BSD2INT(date[6])-1)*60*60*24*Кол_во_дней_в_предыдущих_годах;
//

date[0]=INT2BCD(dt%60);
date[1]=INT2BCD((dt/60)%60);
date[2]=INT2BCD((dt/(60*60))%24);
int i(0);
for(;;)
{
 int n=Кол_секунд_в_годе(i);
 if (dt<n) break;
 dt-=n;
 ++i;
}
date[6]=INT2BCD(i);

i=0;
for(;;)
{
 int n=Кол_во_секунд_в_месяце(i);
 if (dt<n) break;
 dt-=n;
 ++i;
}
date[5]=INT2BCD(i);
date[4]=INT2BCD((dt/(60*60*24)));

А вообще - посмотри исходники стандартных сишных функций, типа gmtime и localtime - они в вижал студии есть.

Автор: Ivan_S 2.9.2004, 12:01
сделал. кому надо - берите
Код

//---------------------------------------------------------------------------
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long

#define BITS1 0x01
#define BITS2 0x03
#define BITS3 0x07
#define BITS4 0x0F
#define BITS5 0x1F
#define BITS6 0x3F
#define BITS7 0x7F
#define BITS8 0xFF

#define PCF8583_sec 0
#define PCF8583_min 1
#define PCF8583_hour 2
#define PCF8583_weekday 3
#define PCF8583_day 4
#define PCF8583_month 5
#define PCF8583_year 6
#define PCF8583_control 7
//---------------------------------------------------------------------------
inline uint BCDINT(uchar bcd, uchar Bits) { bcd&=Bits; return ((bcd)&0x0F)+10*((bcd)>>4); }
inline uchar INTBCD(uint n, uchar Bits) { return ((n%10)|((n/10)<<4))&Bits; }
//----------------------------------------------------------------------------------------------------
ulong MONTH[12]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
//----------------------------------------------------------------------------------------------------
ulong GetSec(const uchar *DateTime){
ulong gYear=BCDINT(DateTime[PCF8583_year], BITS8);
ulong gMonth=BCDINT(DateTime[PCF8583_month], BITS6)-1;
ulong gDate=BCDINT(DateTime[PCF8583_day], BITS6)-1;
ulong gDays=gYear*365+((gYear+3)>>2)+MONTH[gMonth]+((gMonth>1) ?!(gYear%4) :0)+gDate;
ulong gHours=BCDINT(DateTime[PCF8583_hour], BITS6);
ulong gMinutes=BCDINT(DateTime[PCF8583_min], BITS7);
ulong gSeconds=BCDINT(DateTime[PCF8583_sec], BITS7);
gSeconds=(ulong)gDays*86400+gHours*3600+gMinutes*60+gSeconds;
return gSeconds;
}
//----------------------------------------------------------------------------------------------------
void SetSec(uchar *DateTime, ulong Sec){
ulong Back;
Back=Sec; DateTime[PCF8583_sec]=INTBCD(Back-(Sec/=60)*60, BITS7);
Back=Sec; DateTime[PCF8583_min]=INTBCD(Back-(Sec/=60)*60, BITS7);
Back=Sec; DateTime[PCF8583_hour]=INTBCD(Back-(Sec/=24)*24, BITS6);
DateTime[PCF8583_weekday]=INTBCD(((Sec+5)%7)+1, BITS3);
DateTime[PCF8583_year]=INTBCD((Back=Sec*4/1461), BITS8);
Sec-=Back*365+((Back+3)>>2);
int i;
for (i=0; i<12; i++)
 if (MONTH[i]+((Back%4==0 && i>1) ?1 :0)>Sec)
  break;
DateTime[PCF8583_month]=INTBCD(i, BITS6);
DateTime[PCF8583_day]=INTBCD(Sec-MONTH[i-1]-((Back%4==0 && i>2) ?1 :0)+1, BITS6);
}
//----------------------------------------------------------------------------------------------------
// Функции для Builder

#define DateToLong(_data) (long)((double)(_data+TDateTime(0, 0, 0, 10)-TDateTime(2000, 1, 1))*86400)
#define LongToDate(_long) TDateTime((double)(_long)/86400)+TDateTime(2000, 1, 1)
//---------------------------------------------------------------------------
void SetSec(uchar *DateTime, TDateTime D){
unsigned short y, mo, d, h, mi, s, ms;
D.DecodeDate(&y, &mo, &d);
D.DecodeTime(&h, &mi, &s, &ms);
DateTime[PCF8583_sec]=INTBCD(s, BITS7);
DateTime[PCF8583_min]=INTBCD(mi, BITS7);
DateTime[PCF8583_hour]=INTBCD(h, BITS6);
DateTime[PCF8583_day]=INTBCD(d, BITS6);
DateTime[PCF8583_month]=INTBCD(mo, BITS6);
DateTime[PCF8583_year]=INTBCD(y-2000, BITS8);
}
//---------------------------------------------------------------------------
TDateTime GetSec(uchar *DateTime){
return TDateTime(BCDINT(DateTime[PCF8583_year], BITS8), BCDINT(DateTime[PCF8583_month], BITS6)-1,
 BCDINT(DateTime[PCF8583_day], BITS6)-1)+
 TDateTime(BCDINT(DateTime[PCF8583_hour], BITS6), BCDINT(DateTime[PCF8583_min], BITS7),
 BCDINT(DateTime[PCF8583_sec], BITS7), 0);
}
//---------------------------------------------------------------------------


Все функции протестированы. циклически проверены все варианты - результаты сходятся.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)