1 /******************************************************************************
2 *
3 * Copyright (C) 2004-2008, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * Author: Alexey Krivonogov ( gentee )
11 *
12 ******************************************************************************/
13
14 /*-----------------------------------------------------------------------------
15 * Id: datetime L "Date & Time"
16 *
17 * Summary: Functions for working with date and time.
18 *
19 * List: *#lng/opers#,datetime_opeq,datetime_opadd,datetime_opsub,datetime_opdif,
20 datetime_opsum,datetime_opeqeq,datetime_opless,datetime_opgr,
21 *#lng/funcs#,abbrnameofday,days,daysinmonth,firstdayofweek,
22 getdateformat,getdatetime,gettimeformat,isleapyear,nameofmonth,
23 *#lng/methods#,datetime_dayofweek,datetime_dayofyear,datetime_fromstr,
24 datetime_gettime,datetime_getsystime,datetime_normalize,
25 datetime_setdate,datetime_tostr,
26 *File time functions and operators,filetime_opeq,filetime_opeqeq,
27 filetime_opless,filetime_opgr,datetimetoftime,
28 ftimetodatetime,getfiledatetime,
29 *#lng/types#,tdatetime,tfiletime
30 *
31 -----------------------------------------------------------------------------*/
32
33 define
34 {
35 DT_SAVETIME = 0x01 // save sec min hour
36 DT_SAVEDATE = 0x02 // save date
37 DT_SAVEFULL = 0x03
38 DT_REVERSE = 0x10 // обратная запись
39 }
40
41
42 method str datetime.getstr( uint flags, str ret )
43 {
44 if !flags : flags = 0x0F
45
46 ret.clear()
47 if flags & $DT_SAVETIME
48 {
49 if flags & $DT_SAVEDATE || this.hour
50 {
51 ret.printf("%02i%02i%02i", %{ this.second, this.minute, this.hour })
52 }
53 elif this.minute : ret.printf("%02i%02i", %{ this.second, this.minute } )
54 else : ret.printf("%02i", %{this.second} )
55 }
56 if flags & $DT_SAVEDATE
57 {
58 /* if *ret && ( this.year >= 2000 && this.year < 2100 )
59 {
60 ret.printf("%02i%02i%02i", %{ this.day, this.month, this.year - 2000 })
61 }
62 else
63 {*/
64 ret.printf("%02i%02i%04i", %{ this.day, this.month, this.year })
65 // }
66 }
67 if flags & $DT_REVERSE
68 {
69 str rev
70 int i count
71
72 count = *ret / 2
73 if count == 7 || count == 4
74 {
75 rev.substr( ret, *ret - 4, 4 )
76 count -= 2
77 }
78 for i = count, i > 0, i--
79 {
80 uint off = ( i - 1 ) << 1
81
82 rev.appendch( ret[ off ])
83 rev.appendch( ret[ off + 1 ])
84 }
85 ret = "R\( rev )"
86 }
87 return ret
88 }
89
90 /*-----------------------------------------------------------------------------
91 * Id: datetime_tostr F2
92 *
93 * Summary: Convert a datetime structure to string like #b(SSMMHHDDMMYYYY).
94 *
95 * Params: ret - The result string the datetime to be converted to.
96 *
97 * Return: #lng/retpar( ret )
98 *
99 -----------------------------------------------------------------------------*/
100
101 method str datetime.tostr( str ret )
102 {
103 return this.getstr( $DT_SAVEFULL, ret )
104 }
105
106 method str datetime.tostrrev( str ret )
107 {
108 return this.getstr( $DT_SAVEFULL | $DT_REVERSE, ret )
109 }
110
111 /*-----------------------------------------------------------------------------
112 * Id: datetime_fromstr F2
113 *
114 * Summary: Convert string like #b(SSMMHHDDMMYYYY) to datetime structure.
115 *
116 * Params: data - The string to be converted.
117 *
118 * Return: #lng/retobj#
119 *
120 -----------------------------------------------------------------------------*/
121
122 method datetime datetime.fromstr( str data )
123 {
124 uint len = *data
125 str stemp tmp
126 uint pdata
127
128 mzero( &this, sizeof( datetime ))
129 pdata as data
130 if data[0] == 'R'
131 {
132 str year
133 int i start
134
135 if len == 15 || len == 9
136 {
137 year.substr( data, 1, 4 )
138 start = 4
139 }
140 for i = len - 1, i > start, i--
141 {
142 tmp.appendch( data[ i-1 ])
143 tmp.appendch( data[ i-- ])
144 }
145 tmp += year
146 len = *tmp
147 pdata as tmp
148 }
149 if len == 8
150 {
151 this.day = uint( stemp.substr( pdata, 0, 2 ))
152 this.month = uint( stemp.substr( pdata, 2, 2 ))
153 this.year = uint( stemp.substr( pdata, 4, 4 ))
154 return this
155 }
156 this.second = uint( stemp.substr( pdata, 0, 2 ))
157 if len > 2 : this.minute = uint( stemp.substr( pdata, 2, 2 ))
158 if len > 4 : this.hour = uint( stemp.substr( pdata, 4, 2 ))
159 if len > 6
160 {
161 this.day = uint( stemp.substr( pdata, 6, 2 ))
162 this.month = uint( stemp.substr( pdata, 8, 2 ))
163 if len == 12 : this.year = uint( stemp.substr( pdata, 10, 2 )) + 2000
164 else : this.year = uint( stemp.substr( pdata, 10, 4 ))
165 }
166
167 return this
168 }
169
170 /*-----------------------------------------------------------------------------
171 * Id: getdatetime F
172 *
173 * Summary: Getting date and time as strings. Get date and time in the current
174 Windows string format.
175 *
176 * Params: systime - Datetime structure.
177 date - The string for getting the date. It can be 0->str.
178 time - The string for getting time. It can be 0->str.
179 *
180 -----------------------------------------------------------------------------*/
181
182 func getdatetime( datetime systime, str date, str time )
183 {
184 if date
185 {
186 date.setlen( GetDateFormat( 0, 0, systime, 0, date->buf.data,
187 date->buf.size ) - 1 )
188 }
189 if time
190 {
191 time.setlen( GetTimeFormat( 0, 0, systime, 0, time->buf.data,
192 time->buf.size ) - 1 )
193 }
194 }
195
196 /*-----------------------------------------------------------------------------
197 * Id: getdateformat_param D
198 *
199 * Summary: Parameters for getdateformat
200 *
201 -----------------------------------------------------------------------------
202 #define dd 0 // Day as a number.
203 #define ddd 0 // Weekday as an abbriviation.
204 #define dddd 0 // The full name of a weekday.
205 #define MM 0 // Month as a number.
206 #define MMM 0 // Month as an abbreviation.
207 #define MMMM 0 // The full name of a month.
208 #define yy 0 // The last tow digits in a year.
209 #define yyyy 0 // Year.
210
211 //---------------------------------------------------------------------------*/
212
213 /*-----------------------------------------------------------------------------
214 * Id: getdateformat F
215 *
216 * Summary: Get date in the specified format.
217 *
218 * Params: systime - The variable containing date.
219 format - Date format. It can contain the following values:/
220 $$[getdateformat_param]
221 date - The string for getting the date.
222 *
223 * Return: #lng/retpar( date )
224 *
225 -----------------------------------------------------------------------------*/
226
227 func str getdateformat( datetime systime, str format, str date )
228 {
229 date.reserve( 64 )
230 return date.setlen( GetDateFormat( 0, 0, systime, format.ptr(),
231 date.ptr(), 64 ) - 1 )
232 }
233
234 /*-----------------------------------------------------------------------------
235 * Id: gettimeformat_param D
236 *
237 * Summary: Parameters for gettimeformat
238 *
239 -----------------------------------------------------------------------------
240 #define hh 0 // Hours - 12-hour format.
241 #define HH 0 // Hours -24-hour format.
242 #define mm 0 // Minutes.
243 #define ss 0 // Seconds.
244 #define tt 0 // Time marker, such as AM or PM.
245
246 //---------------------------------------------------------------------------*/
247
248 /*-----------------------------------------------------------------------------
249 * Id: gettimeformat F
250 *
251 * Summary: Get time in the specified format.
252 *
253 * Params: systime - The variable containing time.
254 format - Time format. It can contain the following values: /
255 $$[gettimeformat_param]
256 time - The string for getting time.
257 *
258 * Return: #lng/retpar( time )
259 *
260 -----------------------------------------------------------------------------*/
261
262 func str gettimeformat( datetime systime, str format, str time )
263 {
264 time.reserve( 64 )
265 return time.setlen( GetTimeFormat( 0, 0, systime, format.ptr(),
266 time.ptr(), 64 ) - 1 )
267 }
268
269 /*-----------------------------------------------------------------------------
270 * Id: datetime_opeq F4
271 *
272 * Summary: Copying datatime structure.
273 *
274 * Return: The result datetime.
275 *
276 -----------------------------------------------------------------------------*/
277
278 operator datetime =( datetime left, datetime right )
279 {
280 left.year = right.year
281 left.month = right.month
282 left.day = right.day
283 left.hour = right.hour
284 left.minute = right.minute
285 left.second = right.second
286 left.msec = right.msec
287 return left
288 }
289
290 /*-----------------------------------------------------------------------------
291 * Id: datetime_opeqeq F4
292 *
293 * Summary: Comparison operations.
294 *
295 * Return: Returns #b(1) if the datetimes are equal. Otherwise, it returns #b(0).
296 *
297 -----------------------------------------------------------------------------*/
298
299 operator uint ==( datetime left, datetime right )
300 {
301 if left.year != right.year : return 0
302 if left.month != right.month : return 0
303 if left.day != right.day : return 0
304 if left.hour != right.hour : return 0
305 if left.minute != right.minute : return 0
306 if left.second != right.second : return 0
307 if left.msec != right.msec : return 0
308 return 1
309 }
310
311 /*-----------------------------------------------------------------------------
312 * Id: datetime_opeqeq_1 FC
313 *
314 * Summary: Comparison operation.
315 *
316 * Return: Returns #b(0) if the datetimes are equal. Otherwise, it returns #b(1).
317 *
318 * Define: operator uint !=( datetime left, datetime right )
319 *
320 -----------------------------------------------------------------------------*/
321
322 /*-----------------------------------------------------------------------------
323 * Id: datetime_opless F4
324 *
325 * Summary: Comparison operation.
326 *
327 * Title: datetime < datetime
328 *
329 * Return: Returns #b(1) if the first datetime is less than the second one.
330 Otherwise, it returns #b(0).
331 *
332 -----------------------------------------------------------------------------*/
333
334 operator uint <( datetime left, datetime right )
335 {
336 if left.year < right.year : return 1
337 if left.year > right.year : return 0
338 if left.month < right.month : return 1
339 if left.month > right.month : return 0
340 if left.day < right.day : return 1
341 if left.day > right.day : return 0
342 if left.hour < right.hour : return 1
343 if left.hour > right.hour : return 0
344 if left.minute < right.minute : return 1
345 if left.minute > right.minute : return 0
346 if left.second < right.second : return 1
347 if left.second > right.second : return 0
348 if left.msec < right.msec : return 1
349 return 0
350 }
351
352 /*-----------------------------------------------------------------------------
353 * Id: datetime_opless_1 FC
354 *
355 * Summary: Comparison operation.
356 *
357 * Title: datetime <= datetime
358 *
359 * Return: Returns #b(1) if the first datetime is less or equal the second one.
360 Otherwise, it returns #b(0).
361 *
362 * Define: operator uint <=( datetime left, datetime right )
363 *
364 -----------------------------------------------------------------------------*/
365
366 /*-----------------------------------------------------------------------------
367 * Id: datetime_opgr F4
368 *
369 * Summary: Comparison operation.
370 *
371 * Title: datetime > datetime
372 *
373 * Return: Returns #b(1) if the first datetime is greater than the second one.
374 Otherwise, it returns #b(0).
375 *
376 -----------------------------------------------------------------------------*/
377
378 operator uint >( datetime left, datetime right )
379 {
380 if left.year > right.year : return 1
381 if left.year < right.year : return 0
382 if left.month > right.month : return 1
383 if left.month < right.month : return 0
384 if left.day > right.day : return 1
385 if left.day < right.day : return 0
386 if left.hour > right.hour : return 1
387 if left.hour < right.hour : return 0
388 if left.minute > right.minute : return 1
389 if left.minute < right.minute : return 0
390 if left.second > right.second : return 1
391 if left.second < right.second : return 0
392 if left.msec > right.msec : return 1
393 return 0
394 }
395
396 /*-----------------------------------------------------------------------------
397 * Id: datetime_opgr_1 FC
398 *
399 * Summary: Comparison operation.
400 *
401 * Title: datetime >= datetime
402 *
403 * Return: Returns #b(1) if the first datetime is greater or equal the second
404 one. Otherwise, it returns #b(0).
405 *
406 * Define: operator uint >=( datetime left, datetime right )
407 *
408 -----------------------------------------------------------------------------*/
409
410 /*-----------------------------------------------------------------------------
411 * Id: isleapyear F
412 *
413 * Summary: Leap year check.
414 *
415 * Params: year - The year being checked.
416 *
417 * Return: Returns 1 if the year is a leap one and 0 otherwise.
418 *
419 -----------------------------------------------------------------------------*/
420
421 func uint isleapyear( ushort year )
422 {
423 return ?( !( year % 4 ) && ( ( year % 100 ) || !( year % 400 )), 1, 0 )
424 }
425
426 /*-----------------------------------------------------------------------------
427 * Id: daysinmonth F
428 *
429 * Summary: The number of days in a month. Leap years are taken into account
430 for February.
431 *
432 * Params: year - Year.
433 month - Month.
434 *
435 * Return: Returns the number of days in the month.
436 *
437 -----------------------------------------------------------------------------*/
438
439 func uint daysinmonth( ushort year, ushort month )
440 {
441 buf months
442
443 if !month : month = 1
444 if month > 12 : month = 12
445
446 months = '\i 31, \( byte( ?( isleapyear( year ), 29, 28))), 31, 30, 31,
447 30, 31, 31, 30, 31, 30, 31'
448 return uint( months[ month - 1 ] )
449 }
450
451 /*-----------------------------------------------------------------------------
452 * Id: datetime_dayofyear F3
453 *
454 * Summary: Get the number of a particular day in the year.
455 *
456 * Return: Returns the number of a particular day in the year.
457 *
458 -----------------------------------------------------------------------------*/
459
460 method uint datetime.dayofyear
461 {
462 uint i result
463
464 fornum i = 1, this.month
465 {
466 result += daysinmonth( this.year, i )
467 }
468 return result + this.day
469 }
470
471 /*-----------------------------------------------------------------------------
472 * Id: days F
473 *
474 * Summary: The number of days between two dates.
475 *
476 * Params: left - The first date for comparison.
477 right - The second date for comparison.
478 *
479 * Return: Returns the number of days between two dates. If the first date is
480 greater than the second one, the return value will be negative.
481 *
482 -----------------------------------------------------------------------------*/
483
484 func int days( datetime left, datetime right )
485 {
486 uint less great
487 int result
488 uint i
489
490 less as left
491 great as right
492
493 if left > right
494 {
495 less as right
496 great as left
497 }
498
499 for i = less.year, i < great.year, i++
500 {
501 result += ?( isleapyear( i ), 366, 365 )
502 }
503 result -= less.dayofyear()
504 result += great.dayofyear()
505
506 return ?( left > right, -result, result )
507 }
508
509 /*-----------------------------------------------------------------------------
510 * Id: datetime_gettime F3
511 *
512 * Summary: Getting the current date and time. The weekday is set automatically.
513 *
514 * Return: #lng/retobj#
515 *
516 -----------------------------------------------------------------------------*/
517
518 method datetime datetime.gettime()
519 {
520 GetLocalTime( this )
521 return this
522 }
523
524 /*-----------------------------------------------------------------------------
525 * Id: datetime_getsystime F3
526 *
527 * Summary: Getting the current system date and time.
528 *
529 * Return: #lng/retobj#
530 *
531 -----------------------------------------------------------------------------*/
532
533 method datetime datetime.getsystime()
534 {
535 GetSystemTime( this )
536 return this
537 }
538
539 /*-----------------------------------------------------------------------------
540 * Id: datetime_dayofweek F3
541 *
542 * Summary: Get the weekday.
543 *
544 * Return: Returns the weekday. 0 is Sunday, 1 is Monday...
545 *
546 -----------------------------------------------------------------------------*/
547
548 method uint datetime.dayofweek
549 {
550 datetime curtime
551 int dif
552
553 GetLocalTime( curtime )
554 dif = days( this, curtime )
555 this.dayofweek = ( 7 + curtime.dayofweek - ( dif % 7 )) % 7
556 return uint( this.dayofweek )
557 }
558
559 /*-----------------------------------------------------------------------------
560 * Id: datetime_opadd F4
561 *
562 * Summary: Adding days to a date.
563 *
564 * Return: The result datetime.
565 *
566 -----------------------------------------------------------------------------*/
567
568 operator datetime +=( datetime left, uint next )
569 {
570 uint dif i
571 uint curday = left.dayofyear()
572
573 while ( dif = ?( isleapyear( left.year ), 366, 365 ) - curday ) < next
574 {
575 left.year++
576 next -= dif + 1
577 left.month = 1
578 left.day = 1
579 curday = 1
580 }
581 while ( dif = daysinmonth( left.year, left.month ) - left.day ) < next
582 {
583 left.month++
584 next -= dif + 1
585 left.day = 1
586 }
587 left.day += next
588
589 return left
590 }
591
592 /*-----------------------------------------------------------------------------
593 * Id: datetime_opsub F4
594 *
595 * Summary: Subtracting days from a date.
596 *
597 * Return: The result datetime.
598 *
599 -----------------------------------------------------------------------------*/
600
601 operator datetime -=( datetime left, uint next )
602 {
603 uint dif i
604 uint curday = left.dayofyear()
605
606 while curday <= next
607 {
608 left.year--
609 next -= curday
610 left.month = 12
611 left.day = 31
612 curday = ?( isleapyear( left.year ), 366, 365 )
613 }
614 while left.day <= next
615 {
616 left.month--
617 next -= left.day
618 left.day = daysinmonth( left.year, left.month )
619 }
620 left.day -= next
621
622 return left
623 }
624
625 /*-----------------------------------------------------------------------------
626 * Id: datetime_setdate F2
627 *
628 * Summary: Specifying a date. The weekday is set automatically.
629 *
630 * Params: day - Day.
631 month - Month.
632 year - Year.
633 *
634 * Return: #lng/retobj#
635 *
636 -----------------------------------------------------------------------------*/
637
638 method datetime datetime.setdate( uint day, uint month, uint year )
639 {
640 if !year : year = 1
641 if year > 0xFFFF : year = 0xFFFF
642 this.year = year
643 if !month : month = 1
644 if month > 12 : month = 12
645 this.month = month
646 if !day : day = 1
647 if day > daysinmonth( year, month ) : day = daysinmonth( year, month )
648 this.day = day
649 this.dayofweek()
650
651 return this
652 }
653
654 func uint makelangid( uint primary, uint sublang )
655 {
656 return ( sublang << 10 ) | primary
657 }
658
659 func uint makelcid( uint langid, uint sortid )
660 {
661 return ( sortid << 16 ) | langid
662 }
663
664 func uint localeuser()
665 {
666 uint langid = makelangid( $LANG_NEUTRAL, $SUBLANG_DEFAULT )
667 return makelcid( langid, $SORT_DEFAULT)
668 }
669
670 func uint localesystem()
671 {
672 uint langid = makelangid( $LANG_NEUTRAL, $SUBLANG_SYS_DEFAULT )
673 return makelcid( langid, $SORT_DEFAULT )
674 }
675
676 /*-----------------------------------------------------------------------------
677 * Id: nameofmonth F
678 *
679 * Summary: Get the name of a month in the user's language.
680 *
681 * Params: ret - Result string.
682 month - The number of the month from 1.
683 *
684 * Return: #lng/retpar( ret )
685 *
686 -----------------------------------------------------------------------------*/
687
688 func str nameofmonth( str ret, uint month )
689 {
690 if month > 12 : month = 12
691 if !month : month = 1
692 ret.reserve( 32 )
693 GetLocaleInfo( localeuser(),
694 $LOCALE_SMONTHNAME1 + month - 1,
695 ret.ptr(), 32 )
696
697 ret.setlenptr()
698 return ret
699 }
700
701 /*-----------------------------------------------------------------------------
702 * Id: firstdayofweek F1
703 *
704 * Summary: Get the first day of a week for the user's locale.
705 *
706 * Return: Returns the number of the weekday. 0 is Sunday, 1 is Monday...
707 *
708 -----------------------------------------------------------------------------*/
709
710 func uint firstdayofweek()
711 {
712 str ret
713
714 ret.reserve( 8 )
715 GetLocaleInfo( localeuser(),
716 $LOCALE_IFIRSTDAYOFWEEK,
717 ret.ptr(), 8 )
718 ret.setlenptr()
719 return ( uint( ret ) + 1 ) % 7
720
721 }
722
723 /*-----------------------------------------------------------------------------
724 * Id: abbrnameofday F
725 *
726 * Summary: Get the short name of a weekday in the user's language.
727 *
728 * Params: ret - The string for getting the result.
729 dayofweek - The number of the weekday. 0 is Sunday, 1 is Monday...
730 *
731 * Return: #lng/retpar( ret )
732 *
733 -----------------------------------------------------------------------------*/
734
735 func str abbrnameofday( str ret, uint dayofweek )
736 {
737 ret.reserve( 24 )
738
739 dayofweek %= 7
740 if !dayofweek : dayofweek = 7
741
742 GetLocaleInfo( localeuser(),
743 $LOCALE_SABBREVDAYNAME1 + dayofweek - 1,
744 ret.ptr(), 24 )
745 ret.setlenptr()
746 return ret
747 }
748
749 /*-----------------------------------------------------------------------------
750 * Id: filetime_opeq F4
751 *
752 * Summary: Copying filetime structure.
753 *
754 * Return: The result filetime.
755 *
756 -----------------------------------------------------------------------------*/
757
758 operator filetime =( filetime left, filetime right )
759 {
760 left.lowdtime = right.lowdtime
761 left.highdtime = right.highdtime
762
763 return left
764 }
765
766
767 /*-----------------------------------------------------------------------------
768 * Id: filetime_opeqeq F4
769 *
770 * Summary: Comparison operations.
771 *
772 * Return: Returns #b(1) if the filetimes are equal. Otherwise, it returns #b(0).
773 *
774 -----------------------------------------------------------------------------*/
775
776 operator uint ==( filetime left, filetime right )
777 {
778 return !CompareFileTime( left, right )
779 }
780
781 /*-----------------------------------------------------------------------------
782 * Id: filetime_opeqeq_1 FC
783 *
784 * Summary: Comparison operation.
785 *
786 * Return: Returns #b(0) if the filetimes are equal. Otherwise, it returns #b(1).
787 *
788 * Define: operator uint !=( filetime left, filetime right )
789 *
790 -----------------------------------------------------------------------------*/
791
792 /*-----------------------------------------------------------------------------
793 * Id: filetime_opless F4
794 *
795 * Summary: Comparison operation.
796 *
797 * Title: filetime < filetime
798 *
799 * Return: Returns #b(1) if the first filetime is less than the second one.
800 Otherwise, it returns #b(0).
801 *
802 -----------------------------------------------------------------------------*/
803
804 operator uint <( filetime left, filetime right )
805 {
806 return CompareFileTime( left, right ) < 0
807 }
808
809 /*-----------------------------------------------------------------------------
810 * Id: filetime_opless_1 FC
811 *
812 * Summary: Comparison operation.
813 *
814 * Title: filetime <= filetime
815 *
816 * Return: Returns #b(1) if the first filetime is less or equal the second one.
817 Otherwise, it returns #b(0).
818 *
819 * Define: operator uint <=( filetime left, filetime right )
820 *
821 -----------------------------------------------------------------------------*/
822
823 /*-----------------------------------------------------------------------------
824 * Id: filetime_opgr F4
825 *
826 * Summary: Comparison operation.
827 *
828 * Title: filetime > filetime
829 *
830 * Return: Returns #b(1) if the first filetime is greater than the second one.
831 Otherwise, it returns #b(0).
832 *
833 -----------------------------------------------------------------------------*/
834
835 operator uint >( filetime left, filetime right )
836 {
837 return CompareFileTime( left, right ) > 0
838 }
839
840 /*-----------------------------------------------------------------------------
841 * Id: filetime_opgr_1 FC
842 *
843 * Summary: Comparison operation.
844 *
845 * Title: filetime >= filetime
846 *
847 * Return: Returns #b(1) if the first filetime is greater or equal the second
848 one. Otherwise, it returns #b(0).
849 *
850 * Define: operator uint >=( filetime left, filetime right )
851 *
852 -----------------------------------------------------------------------------*/
853
854 /*-----------------------------------------------------------------------------
855 * Id: ftimetodatetime F
856 *
857 * Summary: Converting date from filetime into datetime.
858 *
859 * Params: ft - A structure of the filetime type. Can be taken from the finfo /
860 structure.
861 dt - A datetime structure for getting the result.
862 local - Specify 1 if you need to take the local time into account.
863 *
864 * Return: #lng/retpar( dt )
865 *
866 -----------------------------------------------------------------------------*/
867
868 func datetime ftimetodatetime( filetime ft, datetime dt, uint local )
869 {
870 filetime ftime = ft
871
872 if local : FileTimeToLocalFileTime( ft, ftime )
873 FileTimeToSystemTime( ftime, dt )
874 return dt
875 }
876
877 /*-----------------------------------------------------------------------------
878 * Id: getfiledatetime F
879 *
880 * Summary: Getting date and time as strings. Get the data and time of the last
881 file modification as strings.
882 *
883 * Params: ftime - A structure of the filetime type. Can be taken from /
884 the finfo structure.
885 date - The string for writing date. It can be 0->str.
886 time - The string for writing time. It can be 0->str.
887 *
888 -----------------------------------------------------------------------------*/
889
890 func getfiledatetime( filetime ftime, str date, str time )
891 {
892 datetime st
893
894 ftimetodatetime( ftime, st, 1 )
895 getdatetime( st, date, time )
896 }
897
898 /*-----------------------------------------------------------------------------
899 * Id: datetimetoftime F
900 *
901 * Summary: Converting date from datetime into filetime.
902 *
903 * Params: dt - Datetime structure.
904 ft - The variable of the filetime type for getting the result.
905 local - If it equals 1 then parameter dt is a local time.
906 *
907 * Return: #lng/retf#
908 *
909 -----------------------------------------------------------------------------*/
910
911 func uint datetimetoftime( datetime dt, filetime ft, uint local )
912 {
913 filetime fsystime
914 uint ret
915 ret = SystemTimeToFileTime( dt, fsystime )
916 if local : LocalFileTimeToFileTime( fsystime, ft )
917 else : ft = fsystime
918 return ret
919 //return SystemTimeToFileTime( systime, ft )
920 }
921
922 /*-----------------------------------------------------------------------------
923 * Id: datetimetoftime F8
924 *
925 * Summary: Converting date from datetime into filetime as local time.
926 *
927 * Params: dt - Datetime structure.
928 ft - The variable of the filetime type for getting the result.
929 *
930 -----------------------------------------------------------------------------*/
931
932 func uint datetimetoftime( datetime dt, filetime ft )
933 {
934 return datetimetoftime( dt, ft, 1 )
935 }
936
937 method int short.toint()
938 {
939 int res = this
940 if this & 0x8000
941 {
942 res = res | 0xFFFF0000
943 }
944 return res
945 }
946
947 /*-----------------------------------------------------------------------------
948 * Id: datetime_normalize F3
949 *
950 * Summary: Normalizing a datetime structure. For example, if the hour parameter is 32 hours, it will equal 8 and the day parameter is increased by 1.
951 *
952 * Return: #lng/retobj#
953 *
954 -----------------------------------------------------------------------------*/
955
956 method datetime datetime.normalize()
957 {
958 .second += .msec.toint() / 1000;
959 .msec = .msec.toint() % 1000
960 if .msec.toint() < 0
961 {
962 .second--
963 .msec = 1000 + .msec.toint()
964 }
965
966 .minute += .second.toint() / 60;
967 .second = .second.toint() % 60
968 if .second.toint() < 0
969 {
970 .minute--
971 .second = 60 + .second.toint()
972 }
973
974 .hour += .minute.toint() / 60;
975 .minute = .minute.toint() % 60
976 if .minute.toint() < 0
977 {
978 .hour--
979 .minute = 60 + .minute.toint()
980 }
981
982 .day += .hour.toint() / 24;
983 .hour = .hour.toint() % 24
984 if .hour.toint() < 0
985 {
986 .day--
987 .hour = 24 + .hour.toint()
988 }
989 if .year > 1000
990 {
991 .year += ( .month.toint() - 1 )/12;
992 .month = ( .month.toint() - 1 ) % 12 + 1
993 if .month.toint() < 1
994 {
995 .year--
996 .month = 12 + .month.toint()
997 }
998
999 int offdays = .day - daysinmonth( .year, .month )
1000 .day = daysinmonth( .year, .month )
1001 if offdays > 0: this += offdays
1002 else : this -= -offdays
1003 }
1004 return this
1005 }
1006
1007 /*-----------------------------------------------------------------------------
1008 * Id: datetime_opsum F4
1009 *
1010 * Summary: Adding two dates as days and time. All values are
1011 positive numbers.
1012 *
1013 * Return: The result datetime.
1014 *
1015 -----------------------------------------------------------------------------*/
1016
1017 operator datetime +<result>( datetime left, datetime right )
1018 {
1019 uint nonorm
1020 if right.year.toint() >= 1000 && left.year.toint() >= 1000
1021 {
1022 result = left
1023 return
1024 }
1025
1026 result.hour = left.hour + right.hour
1027 result.minute = left.minute + right.minute
1028 result.second = left.second + right.second
1029 result.msec = left.msec + right.msec
1030
1031 result.year = left.year + right.year
1032 result.month = left.month + right.month
1033 result.day = left.day + right.day
1034
1035 result.normalize()
1036 return
1037 }
1038
1039 /*-----------------------------------------------------------------------------
1040 * Id: datetime_opdif F4
1041 *
1042 * Summary: Difference between two dates as days and time. All values are
1043 positive numbers.
1044 *
1045 * Return: The result datetime.
1046 *
1047 -----------------------------------------------------------------------------*/
1048
1049 operator datetime -<result>( datetime left, datetime right )
1050 {
1051 uint nonorm
1052 if right.year.toint() >= 1000 && left.year.toint() < 1000
1053 {
1054 result = right
1055 return
1056 }
1057
1058 result.hour = left.hour - right.hour
1059 result.minute = left.minute - right.minute
1060 result.second = left.second - right.second
1061 result.msec = left.msec - right.msec
1062
1063 result.day = days( right, left )
1064 /*result.year = left.year - right.year
1065 result.month = left.month - right.month
1066 result.day = left.day - right.day*/
1067
1068 result.normalize()
1069 return
1070 }
1071
1072 /*-----------------------------------------------------------------------------
1073 * Id: datetime_opsum_1 FC
1074 *
1075 * Summary: Adding one datetime to another datetime structure.
1076 *
1077 * Return: The result datetime.
1078 *
1079 -----------------------------------------------------------------------------*/
1080
1081 operator datetime +=( datetime left, datetime right )
1082 {
1083 return left = left + right
1084 }
1085
1086
1087 /*-----------------------------------------------------------------------------
1088 ** Id: datetime_opdif_1 FC
1089 *
1090 * Summary: Difference between two dates as days and time. All values are
1091 positive numbers.
1092 *
1093 * Return: The result datetime.
1094 *
1095 -----------------------------------------------------------------------------*/
1096
1097 operator datetime -=( datetime left, datetime right )
1098 {
1099 return left = left - right
1100 }
1101
1102 /*
1103 operator datetime -<result>( datetime left, datetime right )
1104 {
1105 uint dt shift, xshift
1106
1107 dt as left
1108 result = right
1109
1110 if left > right
1111 {
1112 result = left
1113 dt as right
1114 }
1115 result.year = 0
1116 result.month = 0
1117 result.day = abs( days( left, right ))
1118 if result.msec < dt.msec
1119 {
1120 shift = 1
1121 result.msec += 1000
1122 }
1123 result.msec -= dt.msec
1124 if result.second < dt.second + shift
1125 {
1126 xshift = 1
1127 result.second += 60
1128 }
1129 result.second -= dt.second + shift
1130 shift = 0
1131
1132 if result.minute < dt.minute + xshift
1133 {
1134 shift = 1
1135 result.minute += 60
1136 }
1137 result.minute -= dt.minute + xshift
1138 xshift = 0
1139 if result.hour < dt.hour + shift
1140 {
1141 xshift = 1
1142 result.hour += 24
1143 }
1144 result.hour -= dt.hour + shift
1145 result.day -= xshift
1146
1147 return //result
1148 }
1149 */