Author Topic: обработка дат  (Read 3869 times)

0 Members and 1 Guest are viewing this topic.

Луций

  • Активный участник
  • ***
  • Posts: 248
  • чат в телеге: https://t.me/klickermannchat
    • View Profile
    • Пишу скрипты на заказ:
обработка дат
« on: October 31, 2019, 02:47:08 PM »
возможно кто то писал тут работу с датами джировскими и внутренней кликера?

у меня есть даты в формате "19/авг/19 15:54"

нужно, что бы бот сказал, сколько прошло дней с этой даты в формате "125 дней"

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: обработка дат
« Reply #1 on: October 31, 2019, 10:49:46 PM »
Возможно можно проще, но я решил перевести твою дату в юникс, и по разнице секунд определить количество дней.
Формулу нигде не искал, не копировал, написал сам, такчто возможно с чемто и ошибся. Знающие поправят.
Code: (clickermann) [Select]
IF(int(($_date_y-1968)/4) = ($_date_y-1968)/4)         //определяем, високосный ли год
  STRSEPARATE ("31,29,31,30,31,30,31,31,30,31,30,31", ",", $month) //массив с месяцами
ELSE
  STRSEPARATE ("31,28,31,30,31,30,31,31,30,31,30,31", ",", $month)
END_IF

FOR($a=0,$a<$_date_m-1)       // определяем количество дней до начала месяца
   $all_md  = $month[$a] + $all_md
END_CYC

$unix =(($_date_y-1970)*365+int(($_date_y-1969)/4))*86400 + $all_md*86400 + ($_date_d-1)*86400 + $_time_h*3600 + $_time_m*60 + $_time_s

print("рассчитанное время юникс - ",$unix) //пока писал, на данный момент все верно.
print("реальное время юникс - ",$_time_t)

halt


Вариант для твоей задачи:
Code: (clickermann) [Select]
$date = "19/авг/19 15:54"   //написал простой вариант, где к однозначным числам приклеивается 0 , к примеру 19/авг/01 04:09

$date_y = int(STRCUT ($date, 8, 2)) + 2000

$date_m = STRCUT ($date, 4, 3)
STRSEPARATE ("янв,фев,мар,апр,май,июн,июл,авг,сен,окт,ноя,дек", ",", $mon)
FOR($a=0,$a<12)
   IF($mon[$a] = $date_m)
      $date_m = $a+1
      $a=12
   END_IF   
END_CYC

$date_d = int(STRCUT ($date, 1, 2))

$time_h = int(STRCUT ($date, 11, 2))

$time_m  = int(STRCUT ($date, 14, 2))

//print($date_y, " ", $date_m, " ", $date_d, " ", $time_h, " ", $time_m)

//////////////////////////////////////

IF(int(($date_y-1968)/4) = ($date_y-1968)/4)
  STRSEPARATE ("31,29,31,30,31,30,31,31,30,31,30,31", ",", $month)
ELSE
  STRSEPARATE ("31,28,31,30,31,30,31,31,30,31,30,31", ",", $month)
END_IF

FOR($a=0,$a<$date_m-1)     
   $all_md  = $month[$a] + $all_md
END_CYC

$unix =(($date_y-1970)*365+int(($date_y-1969)/4))*86400 + $all_md*86400 + ($date_d-1)*86400 + $time_h*3600 + $time_m*60

//print("рассчитанное время в юникс - ", $unix)

$days = int(($_time_t - $unix)/86400)

print("Прошло ", $days, " дней")   //Прошло 73 дней

halt


« Last Edit: October 31, 2019, 10:55:23 PM by dramster »

Луций

  • Активный участник
  • ***
  • Posts: 248
  • чат в телеге: https://t.me/klickermannchat
    • View Profile
    • Пишу скрипты на заказ:
Re: обработка дат
« Reply #2 on: November 01, 2019, 02:01:05 AM »
спс за работу, вот эта длинная мне нужна была в основном, еще и про высокосные года я совсем забыл

Vint

  • Супермодератор
  • Герой форума
  • *
  • Posts: 3935
  • Лечу куда хочу. cman 4.13.014x32, 4.14.003 W10
    • View Profile
Re: обработка дат
« Reply #3 on: November 01, 2019, 08:59:30 AM »
Почти правильно  :)
Ты забыл учесть года кратные 100, как минимум один такой был от старта эпохи UNIX это 2000 год.
Поэтому все вычисления после показывают на 1 день меньше.

Quote
год, номер которого кратен 400, — високосный;
остальные годы, номер которых кратен 100, — невисокосные;

А может не поэтому  ::)
Обычно все калькуляторы в таком случае считают переключившийся день, а не секунды в дни переводит.
При данном способе, как в коде, мы считаем сколько прошло полных 24-часовых промежутков. Это подходит только в случае если нам нужно учитывить короткие процессы (секунды-минуты-часы).
Если нам нужно учитывать именно календарные дни, то так неправильно. С вчерашних 15 часов до сегодняшних 9 прошёл 1 день (по календарю) значит должно выводить 1, дата то сменилась.
« Last Edit: November 01, 2019, 09:26:02 AM by Vint »


dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Re: обработка дат
« Reply #4 on: November 01, 2019, 07:50:20 PM »
Поэтому все вычисления после показывают на 1 день меньше.

Quote
год, номер которого кратен 400, — високосный;
остальные годы, номер которых кратен 100, — невисокосные;

А может не поэтому  ::)
Про каждый сотый год не знал  :-\ . Но вычисления все правильные, так как 2000 год в любом случае висакосный, и без учета кратности 100 он висакосный, но в то же время он кратен 400. Никакого дня добавлять не нужно. Другое дело если бы был 2100-е годы ...  :D .
Но ты потом все верно подметил, нестыковка была изза того, что рассчеты идут именно  в "полных 24-часовых промежутках".


А по поводу подсчета именно календарных дней, то можно оставить эти все расчеты юникс как есть, хер с ними, нужно просто исправить последний рассчет :
Code: (clickermann) [Select]
$days = int($_time_t/86400) - int($unix/86400)

Graubart

  • Освоившийся
  • **
  • Posts: 44
  • Alles wird gut
    • View Profile
Re: обработка дат
« Reply #5 on: November 02, 2019, 05:48:45 PM »

Когда-то в одном проекте я столкнулся с этой задачей. Но там речь шла о больших промежутках лет, до тысяч. Хотел сначала тоже через Unix-время решить, но там зашел в минуса и сложности. Сделал через подсчет количества лет с начала новой эры с учетом високосных дней. Точность 100%, но только по григорианскому календарю.
В КМ это будет выглядеть так:

Code: (clickermann) [Select]
// Массив к-ва дней на начало каждого месяца
 $num_days[1]=0
 $num_days[2]=31
 $num_days[3]=59
 $num_days[4]=90
 $num_days[5]=120
 $num_days[6]=151
 $num_days[7]=181
 $num_days[8]=212
 $num_days[9]=243
 $num_days[10]=273
 $num_days[11]=304
 $num_days[12]=334
// Начальная дата цифрами
 $day_0=15
 $month_0=8
 $year_0=2019
// Конечная дата, можно вставить любую
 $day_1=$_date_d
 $month_1=$_date_m
 $year_1=$_date_y
// К-во високосных дней
 $leap_year_0=(($year_0-4*INT($year_0/4)=0) AND ($year_0>0 OR INT($year_0/100)-4*INT(($year_0/100)/4)=0))
// К-во прошедших дней с начала новой эры
 $num_d_0=365*($year_0-1)+INT(($year_0-1)/4)+$num_days[$month_0]+$day_0+($month_0>2)*$leap_year_0
 $leap_year_1=(($year_1-4*INT($year_1/4)=0) AND ($year_1>0 OR INT($year_1/100)-4*INT(($year_1/100)/4)=0))
 $num_d_1=365*($year_1-1)+INT(($year_1-1)/4)+$num_days[$month_1]+$day_1+($month_1>2)*$leap_year_1
//Разница дней
 $dif_day=$num_d_1-$num_d_0
   HALT
Просто объяснить сложное - сложно. Сложно объяснить сложное - просто.
• Альберт Эйнштейн