summaryrefslogtreecommitdiff
path: root/mbglib/common/mbgtime.h
blob: 2c5c50e0590e2f825a96c920a9332f8c3ea3c114 (plain)
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652

/**************************************************************************
 *
 *  $Id: mbgtime.h 1.23.1.3 2017/03/17 11:33:05 martin TEST $
 *
 *  Copyright (c) Meinberg Funkuhren, Bad Pyrmont, Germany
 *
 *  Description:
 *    Definitions and prototypes for mbgtime.c.
 *
 * -----------------------------------------------------------------------
 *  $Log: mbgtime.h $
 *  Revision 1.23.1.3  2017/03/17 11:33:05  martin
 *  *** empty log message ***
 *  Revision 1.23.1.2  2017/03/17 10:36:41  martin
 *  *** empty log message ***
 *  Revision 1.23.1.1  2017/03/16 15:24:46  martin
 *  Updated preliminary function prototypes.
 *  Revision 1.23  2017/03/16 12:26:13  martin
 *  Updated function prototypes.
 *  Revision 1.22  2017/01/25 13:10:55  gregoire.diehl
 *  nano_time_64_to_double and double_to_nano_time_64 added
 *  Revision 1.21  2016/12/15 17:44:59Z  martin
 *  Changed conditions to include time.h.
 *  Fixed spelling.
 *  Removed trailing spaces.
 *  Revision 1.20  2014/05/27 08:09:19  martin
 *  Added NTP_SEC_BIAS.
 *  Revision 1.19  2013/05/22 16:47:01  martin
 *  Added some useful macros.
 *  Revision 1.18  2012/10/02 18:51:11  martin
 *  Include <time.h> for WIN32 target and firmware only
 *  Fixed build under QNX, DOS, and FreeBSD.
 *  Revision 1.17  2010/08/06 13:03:03  martin
 *  Removed obsolete code.
 *  Revision 1.16  2010/07/16 10:22:07Z  martin
 *  Moved definitions of HNS_PER_SEC and HNS_PER_MS here.
 *  Conditionally define FILETIME_1970.
 *  Defined MASK_CLOCK_T for ARM/Cortex.
 *  Revision 1.15  2009/10/23 09:55:21  martin
 *  Added MJD numbers for commonly used epochs.
 *  Revision 1.14  2009/08/12 10:28:12  daniel
 *  Added definition NSECS_PER_SEC.
 *  Revision 1.13  2009/06/12 13:31:44Z  martin
 *  Fix build errors with arm-linux-gcc.
 *  Revision 1.12  2009/03/27 14:14:00  martin
 *  Cleanup for CVI.
 *  Revision 1.11  2009/03/13 09:30:06Z  martin
 *  Include mystd.h in mbgtime.c rather than here. The bit type used
 *  here is now defined in words.h.
 *  Updated comments for GPS_SEC_BIAS.
 *  Revision 1.10  2008/12/11 10:45:41Z  martin
 *  Added clock_t mask for gcc (GnuC).
 *  Revision 1.9  2006/08/25 09:33:46Z  martin
 *  Updated function prototypes.
 *  Revision 1.8  2004/12/28 11:29:02Z  martin
 *  Added macro _n_days.
 *  Updated function prototypes.
 *  Revision 1.7  2002/09/06 07:15:48Z  martin
 *  Added MASK_CLOCK_T for Linux.
 *  Revision 1.6  2002/02/25 08:37:44  Andre
 *  definition MASK_CLOCK_T for ARM added
 *  Revision 1.5  2001/03/02 10:18:10Z  MARTIN
 *  Added MASK_CLOCK_T for Watcom C.
 *  Revision 1.4  2000/09/15 07:57:53  MARTIN
 *  Removed outdated function prototypes.
 *  Revision 1.3  2000/07/21 14:05:18  MARTIN
 *  Defined some new constants.
 *
 **************************************************************************/

#ifndef _MBGTIME_H
#define _MBGTIME_H


/* Other headers to be included */

#include <gpsdefs.h>

#if !defined( MBG_TGT_KERNEL ) || defined( MBG_TGT_WIN32 )
  #include <time.h>
#endif


#ifdef __cplusplus
extern "C" {
#endif

#ifdef _MBGTIME
 #define _ext
 #define _DO_INIT
#else
 #define _ext extern
#endif


/* Start of header body */


/**
 * @brief GPS epoch bias from ordinary time_t epoch
 *
 * The Unix time_t epoch is usually 1970-01-01 00:00 whereas
 * the GPS epoch is 1980-01-06 00:00, so the difference is 10 years,
 * plus 2 days due to leap years (1972 and 1976), plus the difference
 * of the day-of-month (6 - 1), so:<br>
 *
 * time_t t = ( gps_week * ::SECS_PER_WEEK ) + sec_of_week + ::GPS_SEC_BIAS
 */
#define GPS_SEC_BIAS   315964800UL     // ( ( ( 10UL * 365UL ) + 2 + 5 ) * SECS_PER_DAY )


/**
 * @brief NTP epoch bias from ordinary time_t epoch
 *
 * The Unix time_t epoch is usually 1970-01-01 00:00 whereas
 * the NTP epoch is 1900-01-01 00:00, so the difference is
 * a constant number of seconds:<br>
 *
 * time_t t = ntp_time - ::NTP_SEC_BIAS
 */
#define NTP_SEC_BIAS   2208988800UL



// Modified Julian Day (MJD) numbers for some commonly used epochs.
// To compute the MJD for a given date just compute the days since epoch
// and add the constant number of days according to the epoch, e.g.:
//   current_unix_mjd = ( time( NULL ) / SECS_PER_DAY ) + MJD_AT_UNIX_EPOCH;
#define MJD_AT_GPS_EPOCH    44244UL    // MJD at 1980-01-06
#define MJD_AT_UNIX_EPOCH   40587UL    // MJD at 1970-01-01
#define MJD_AT_NTP_EPOCH    40587UL    // MJD at 1900-01-01


// The constant below defines the Windows FILETIME number (100 ns intervals
// since 1601-01-01) for 1970-01-01, which is usually the epoch for the time_t
// type used by the standard C library.
#if !defined( FILETIME_1970 )
  // FILETIME represents a 64 bit number, so we need to defined the
  // constant with an appendix depending on the compiler.
  #if MBG_TGT_C99 || defined( __GNUC__ )
    // syntax introduced by C99 standard
    #define FILETIME_1970    0x019db1ded53e8000ULL  // Epoch offset from FILETIME to UNIX
  #elif defined( MBG_TGT_WIN32 )
    // MSC-specific syntax
    #define FILETIME_1970    0x019db1ded53e8000ui64
  #endif
#endif


#if defined( _C166 )
  #if _C166 >= 50
    #define MASK_CLOCK_T 0x7FFFFFFFL
  #else
    #define MASK_CLOCK_T 0x7FFF   /* time.h not shipped with compiler */
  #endif
#endif

#if defined( __WATCOMC__ )
  #define MASK_CLOCK_T 0x7FFFFFFFL
#endif

#if defined( _CVI ) || defined( _CVI_ )
  #define MASK_CLOCK_T 0x7FFFFFFFL
#endif

#if defined( _MSC_VER )
  #define MASK_CLOCK_T 0x7FFFFFFFL
#endif

#if defined( __NETWARE_386__ )
  #define MASK_CLOCK_T 0x7FFFFFFFL
#endif

#if defined( __ARM )
  #define MASK_CLOCK_T 0x7FFFFFFFL
#endif

#if defined( __ARMCC_VERSION )
  #define MASK_CLOCK_T ( ( (ulong) (clock_t) -1 ) >> 1 )
#endif

#if defined( __GNUC__ )
  #if defined( __linux )
    #define MASK_CLOCK_T ( ( (ulong) (clock_t) -1 ) >> 1 )
  #else  // Windows / MinGW
    #define MASK_CLOCK_T 0x7FFFFFFFL
  #endif
#endif


#if !defined( MASK_CLOCK_T )
  #if sizeof( clock_t ) == sizeof( short )
    #define MASK_CLOCK_T 0x7FFF
  #elif sizeof( clock_t ) == sizeof( long )
    #define MASK_CLOCK_T 0x7FFFFFFFL
  #endif
#endif

typedef struct
{
  clock_t start;
  clock_t stop;
  short is_set;

} TIMEOUT;


#define DAYS_PER_WEEK     7

#define SECS_PER_MIN      60
#define MINS_PER_HOUR     60
#define HOURS_PER_DAY     24
#define DAYS_PER_WEEK     7

#define MINS_PER_DAY      ( MINS_PER_HOUR * HOURS_PER_DAY )

#define SECS_PER_HOUR     3600
#define SECS_PER_DAY      86400L
#define SECS_PER_WEEK     604800L

#define SEC100S_PER_SEC   100L
#define SEC100S_PER_MIN   ( SEC100S_PER_SEC * SECS_PER_MIN )
#define SEC100S_PER_HOUR  ( SEC100S_PER_SEC * SECS_PER_HOUR )
#define SEC100S_PER_DAY   ( SEC100S_PER_SEC * SECS_PER_DAY )

#if !defined( MSEC_PER_SEC )
  #define MSEC_PER_SEC   1000L
#endif

#define MSEC_PER_MIN   ( MSEC_PER_SEC * SECS_PER_MIN )
#define MSEC_PER_HOUR  ( MSEC_PER_SEC * SECS_PER_HOUR )
#define MSEC_PER_DAY   ( MSEC_PER_SEC * SECS_PER_DAY )

#define NSECS_PER_SEC     1000000000UL

#if !defined( HNS_PER_SEC )
  #define HNS_PER_SEC       10000000UL
#endif

#if !defined( HNS_PER_MS )
  #define HNS_PER_MS          10000UL
#endif


/**
 * @brief A table with the days of month
 *
 * First row is for standard years, second row is
 * for leap years.
 *
 * @see DAYS_OF_MONTH_TABLE_INIT
 */
typedef char DAYS_OF_MONTH_TABLE[2][12];


/**
 * @brief An initializer for a ::DAYS_OF_MONTH_TABLE
 */
#define DAYS_OF_MONTH_TABLE_INIT                      \
{                                                     \
  { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, \
  { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }  \
}




_ext TM_GPS dhms;
_ext TM_GPS datum;


_ext const char *short_time_fmt
#ifdef _DO_INIT
 = "%2i:%02i"
#endif
;

_ext const char *time_fmt
#ifdef _DO_INIT
 = "%2i:%02i:%02i"
#endif
;

_ext const char *long_time_fmt
#ifdef _DO_INIT
 = "%2i:%02i:%02i.%02i"
#endif
;

_ext const char *date_fmt
#ifdef _DO_INIT
 = "%2i.%02i.%04i"
#endif
;

_ext const char *day_date_fmt
#ifdef _DO_INIT
 = "%s, %2i.%02i.%04i"
#endif
;

_ext const char *day_name_eng[]
#ifdef _DO_INIT
 = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" }
#endif
;

_ext const char *day_name_ger[]
#ifdef _DO_INIT
 = { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" }
#endif
;

_ext const TM_GPS init_tm
#ifdef _DO_INIT
  = { 1980, 1, 1, 0, 0, 0, 0, 0, 0, 0 }
#endif
;


_ext DAYS_OF_MONTH_TABLE days_of_month
#ifdef _DO_INIT
 = DAYS_OF_MONTH_TABLE_INIT
#endif
;


// simplify call to n_days with structures
#define _n_days( _s ) \
  n_days( (_s)->mday, (_s)->month, (_s)->year )


#define _is_leap_year( _y ) \
  ( ( ( ( (_y) % 4 ) == 0 ) && ( ( (_y) % 100 ) != 0 ) ) || ( ( (_y) % 400 ) == 0 ) )


#define _get_days_of_month( _y, _m ) \
  days_of_month[ _is_leap_year( _y ) ][_m]



/* ----- function prototypes begin ----- */

/* This section was generated automatically */
/* by MAKEHDR, do not remove the comments. */

 /**
 * @brief Set a timeout object to specified interval
 *
 * @param[out]  t         The timeout object
 * @param[in]   clk       The current time, in clock_t ticks
 * @param[in]   interval  The interval until expiration, in clock_t ticks
 */
 void set_timeout( TIMEOUT *t, clock_t clk, clock_t interval ) ;

 /**
 * @brief Stretch a timeout specified in given timeout object
 *
 * @param[in,out]  t         The timeout object
 * @param[in]      interval  The interval until expiration, in clock_t ticks
 */
 void stretch_timeout( TIMEOUT *t, clock_t interval ) ;

 /**
 * @brief Check if a timeout object has expired
 *
 * @param[in]  t    The timeout object
 * @param[in]  clk  The current time, in clock_t ticks
 *
 * @return 1 if timeout expired, else 0
 */
 bit check_timeout( TIMEOUT *t, clock_t clk ) ;

 /**
 * @brief Check if a ::TM_GPS structure contains a valid date and time
 *
 * @param[in]  tm   The date/time structure to be checked
 *
 * @return 0 if date/time is valid, else a negative number indicating
 *         which field was found invalid
 */
 int err_tm( const TM_GPS *tm ) ;

 /**
 * @brief Set the time in a ::TM_GPS structure to 00:00:00
 *
 * FIXME what about the frac and UTC offset fields?
 *
 * @param[in]  tm   The date/time structure to be set
 *
 * @return Pointer to the ::TM_GPS structure that has been passed
 */
 TM_GPS *clear_time( TM_GPS *tm ) ;

 /**
 * @brief Convert second-of-week to day-of-week and time-of-day
 *
 * @param[in]   wsec  The second-of-week number to be converted
 * @param[out]  tm    Address of a ::TM_GPS structure which takes the computed results
 *
 * @return  Pointer to the ::TM_GPS structure that has been passed
 *
 * @see ::tm_to_wsec
 */
 TM_GPS *wsec_to_tm( long wsec, TM_GPS *tm ) ;

 /**
 * @brief Compute second-of-week from day-of-week and time-of-day
 *
 * @todo Specify input / output ranges
 *
 * @param[in]  tm  Address of a ::TM_GPS structure providing day-of-week and time-of-day
 *
 * @return The computed second-of-week number
 *
 * @see ::wsec_to_tm
 */
 long tm_to_wsec( const TM_GPS *tm ) ;

 /**
 * @brief Check if a specific year is a leap year
 *
 * @param[in]  y  The full year number
 *
 * @return  != 0 if the year is a leap year, else 0
 */
 int is_leap_year( int y ) ;

 /**
 * @brief Compute the day-of-year from a given date
 *
 * @param[in]  day    The day-of-month
 * @param[in]  month  The month
 * @param[in]  year   The full year number
 *
 * @return The computed day-of-year
 */
 int day_of_year( int day, int month, int year ) ;

 /**
 * @brief Compute a date from a given year and day-of-year
 *
 * @param[in]   year     The full year number
 * @param[in]   day_num  Number of days from the beginning of that year, may be negative
 * @param[out]  tm       Address of a ::TM_GPS structure which takes the computed results
 */
 void date_of_year ( int year, int day_num, TM_GPS *tm ) ;

 /**
 * @brief Compute day-of-week from a given date
 *
 * @todo Specify range of returned day-of-week. Should we just call n_days()?
 *
 * @param[in]  day    The day-of-month
 * @param[in]  month  The month
 * @param[in]  year   The full year number
 *
 * @return The computed day-of-week
 *
 * @see ::n_days
 */
 int day_of_week( int day, int month, int year ) ;

 /**
 * @brief FIXME Compute yearday-of-week from a given date
 *
 * @todo Specify range of returned day-of-week
 *
 * @param[in]  day    The day-of-month
 * @param[in]  month  The month
 * @param[in]  year   The full year number
 *
 * @return The computed day-of-week
 */
 int days_to_years( long *day_num, int year ) ;

 /**
 * @brief Compute number of days after Jan 1, 0000 for a given date
 *
 * @param[in]  mday   The day-of-month
 * @param[in]  month  The month
 * @param[in]  year   The full year number
 *
 * @return The computed number of days
 *
 * @see ::day_of_week
 */
 long n_days( ushort mday, ushort month, ushort year ) ;

 /**
 * @brief Convert a ::NANO_TIME time to double
 *
 * @param[in]  p  Address of a ::NANO_TIME structure to be converted
 *
 * @return The computed number of seconds with fractions, as double
 *
 * @see ::double_to_nano_time
 */
 double nano_time_to_double( const NANO_TIME *p ) ;

 /**
 * @brief Setup a ::NANO_TIME structure from a time provided as double
 *
 * @param[out]  p  Address of a ::NANO_TIME structure to be set up
 * @param[in]   d  The time to be converted, in seconds with fractions, as double
 *
 * @see ::nano_time_to_double
 */
 void double_to_nano_time( NANO_TIME *p, double d ) ;

 /**
 * @brief Convert a ::NANO_TIME_64 time to double
 *
 * @param[in]  p  Address of a ::NANO_TIME_64 structure to be converted
 *
 * @return The computed number of seconds with fractions, as double
 *
 * @see ::double_to_nano_time_64
 */
 double nano_time_64_to_double( const NANO_TIME_64 *p ) ;

 /**
 * @brief Setup a ::NANO_TIME_64 structure from a time as double
 *
 * @param[out]  p  Address of a ::NANO_TIME_64 structure to be set up
 * @param[in]   d  The time to be converted, in seconds with fractions, as double
 *
 * @see ::nano_time_64_to_double
 */
 void double_to_nano_time_64( NANO_TIME_64 *p, double d ) ;

 /**
 * @brief Set up a ::NANO_TIME_64 structure from a string with a time in seconds and fractions
 *
 * @param[in]   s  A string with a time in seconds, with fractions separated by decimal point
 * @param[out]  p  Address of a ::NANO_TIME_64 structure to be set up
 */
 void str_s_to_nano_time_64( const char *s, NANO_TIME_64 *p ) ;

 /**
 * @brief Set up a ::NANO_TIME_64 structure from a string with a time in milliseconds and fractions
 *
 * @param[in]   s  A string with a time in milliseconds, with fractions separated by decimal point
 * @param[out]  p  Address of a ::NANO_TIME_64 structure to be set up
 */
 void str_ms_to_nano_time_64( const char *s, NANO_TIME_64 *p ) ;

 /**
 * @brief Convert a ::NTP_TSTAMP structure to a ::NANO_TIME_64 structure
 *
 * @param[in]   p_nts   The ::NTP_TSTAMP structure to be converted
 * @param[out]  p_nt64  The ::NANO_TIME_64 structure to be filled up
 */
 void ntp_tstamp_to_nanotime_64( const NTP_TSTAMP *p_nts, NANO_TIME_64 *p_nt64 ) ;

 /**
 * @brief Set up a ::NTP_TSTAMP structure from a hex string with a time in seconds and binary fractions
 *
 * @param[in]   s  A string with a time in seconds since epoch 1900-01-01,
 *                 with binary fractions separated by decimal point,
 *                 e.g. 'dc763e43.73bd5a8f' as printed by the ntpq utility
 * @param[out]  p  Address of a ::NANO_TIME_64 structure to be set up
 *
 * @see ::str_ntp_hex_to_nano_time_64
 */
 void str_ntp_hex_to_ntp_tstamp( const char *s, NTP_TSTAMP *p ) ;

 /**
 * @brief Set up a ::NANO_TIME_64 structure from a hex string with a time in seconds and binary fractions
 *
 * @param[in]   s  A string with a time in seconds since epoch 1900-01-01,
 *                 with binary fractions separated by decimal point,
 *                 e.g. 'dc763e43.73bd5a8f' as printed by the ntpq utility
 * @param[out]  p  Address of a ::NANO_TIME_64 structure to be set up
 *
 * @see ::str_ntp_hex_to_ntp_tstamp
 */
 void str_ntp_hex_to_nano_time_64( const char *s, NANO_TIME_64 *p ) ;

 /**
 * @brief Print time with hours, minutes, seconds to a string
 *
 * @param[out]  s   Address of a string buffer to be filled
 * @param[in]   tm  Address of a ::TM_GPS structure providing date and time
 */
 int sprint_time( char *s, const TM_GPS *tm ) ;

 /**
 * @brief Print time with hours, minutes to a string
 *
 * @param[out]  s   Address of a string buffer to be filled
 * @param[in]   tm  Address of a ::TM_GPS structure providing date and time
 */
 int sprint_short_time( char *s, TM_GPS *time ) ;

 /**
 * @brief Print date to a string
 *
 * @param[out]  s   Address of a string buffer to be filled
 * @param[in]   tm  Address of a ::TM_GPS structure providing date and time
 */
 int sprint_date( char *s, const TM_GPS *tm ) ;

 /**
 * @brief Print day-of-week and date to a string
 *
 * @param[out]  s   Address of a string buffer to be filled
 * @param[in]   tm  Address of a ::TM_GPS structure providing date and time
 */
 int sprint_day_date( char *s, const TM_GPS *tm ) ;

 /**
 * @brief Print day-of-week, date and time to a string
 *
 * @param[out]  s   Address of a string buffer to be filled
 * @param[in]   tm  Address of a ::TM_GPS structure providing date and time
 */
 int sprint_tm( char *s, const TM_GPS *tm ) ;

 /**
 * @brief Extract a time from a string
 *
 * @param[in]   s   A time string in format hh:mm:ss
 * @param[out]  tm  Address of a ::TM_GPS structure which takes the extracted time
 */
 void sscan_time( const char *s, TM_GPS *tm ) ;

 /**
 * @brief Extract a date from a string
 *
 * @param[in]   s   A date string in format dd.mm. or dd.mm.yyyy
 * @param[out]  tm  Address of a ::TM_GPS structure which takes the extracted date
 */
 void sscan_date( char *s, TM_GPS *tm ) ;


/* ----- function prototypes end ----- */


/* End of header body */


#undef _ext
#undef _DO_INIT

#ifdef __cplusplus
}
#endif


#endif  /* _MBGTIME_H */