1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module glib.Date; 26 27 private import glib.ConstructionException; 28 private import glib.MemorySlice; 29 private import glib.Str; 30 private import glib.TimeVal; 31 private import glib.c.functions; 32 public import glib.c.types; 33 private import gtkd.Loader; 34 35 36 /** 37 * Represents a day between January 1, Year 1 and a few thousand years in 38 * the future. None of its members should be accessed directly. 39 * 40 * If the #GDate-struct is obtained from g_date_new(), it will be safe 41 * to mutate but invalid and thus not safe for calendrical computations. 42 * 43 * If it's declared on the stack, it will contain garbage so must be 44 * initialized with g_date_clear(). g_date_clear() makes the date invalid 45 * but safe. An invalid date doesn't represent a day, it's "empty." A date 46 * becomes valid after you set it to a Julian day or you set a day, month, 47 * and year. 48 */ 49 public final class Date 50 { 51 /** the main Gtk struct */ 52 protected GDate* gDate; 53 protected bool ownedRef; 54 55 /** Get the main Gtk struct */ 56 public GDate* getDateStruct(bool transferOwnership = false) 57 { 58 if (transferOwnership) 59 ownedRef = false; 60 return gDate; 61 } 62 63 /** the main Gtk struct as a void* */ 64 protected void* getStruct() 65 { 66 return cast(void*)gDate; 67 } 68 69 /** 70 * Sets our main struct and passes it to the parent class. 71 */ 72 public this (GDate* gDate, bool ownedRef = false) 73 { 74 this.gDate = gDate; 75 this.ownedRef = ownedRef; 76 } 77 78 ~this () 79 { 80 if ( Linker.isLoaded(LIBRARY_GLIB) && ownedRef ) 81 g_date_free(gDate); 82 } 83 84 85 /** 86 * the Julian representation of the date 87 */ 88 public @property uint julianDays() 89 { 90 return gDate.julianDays; 91 } 92 93 /** Ditto */ 94 public @property void julianDays(uint value) 95 { 96 gDate.julianDays = value; 97 } 98 99 /** 100 * this bit is set if @julian_days is valid 101 */ 102 public @property uint julian() 103 { 104 return gDate.julian; 105 } 106 107 /** Ditto */ 108 public @property void julian(uint value) 109 { 110 gDate.julian = value; 111 } 112 113 /** 114 * this is set if @day, @month and @year are valid 115 */ 116 public @property uint dmy() 117 { 118 return gDate.dmy; 119 } 120 121 /** Ditto */ 122 public @property void dmy(uint value) 123 { 124 gDate.dmy = value; 125 } 126 127 /** 128 * the day of the day-month-year representation of the date, 129 * as a number between 1 and 31 130 */ 131 public @property uint day() 132 { 133 return gDate.day; 134 } 135 136 /** Ditto */ 137 public @property void day(uint value) 138 { 139 gDate.day = value; 140 } 141 142 /** 143 * the day of the day-month-year representation of the date, 144 * as a number between 1 and 12 145 */ 146 public @property uint month() 147 { 148 return gDate.month; 149 } 150 151 /** Ditto */ 152 public @property void month(uint value) 153 { 154 gDate.month = value; 155 } 156 157 /** 158 * the day of the day-month-year representation of the date 159 */ 160 public @property uint year() 161 { 162 return gDate.year; 163 } 164 165 /** Ditto */ 166 public @property void year(uint value) 167 { 168 gDate.year = value; 169 } 170 171 /** 172 * Allocates a #GDate and initializes 173 * it to a safe state. The new date will 174 * be cleared (as if you'd called g_date_clear()) but invalid (it won't 175 * represent an existing day). Free the return value with g_date_free(). 176 * 177 * Returns: a newly-allocated #GDate 178 * 179 * Throws: ConstructionException GTK+ fails to create the object. 180 */ 181 public this() 182 { 183 auto __p = g_date_new(); 184 185 if(__p is null) 186 { 187 throw new ConstructionException("null returned by new"); 188 } 189 190 this(cast(GDate*) __p); 191 } 192 193 /** 194 * Like g_date_new(), but also sets the value of the date. Assuming the 195 * day-month-year triplet you pass in represents an existing day, the 196 * returned date will be valid. 197 * 198 * Params: 199 * day = day of the month 200 * month = month of the year 201 * year = year 202 * 203 * Returns: a newly-allocated #GDate initialized with @day, @month, and @year 204 * 205 * Throws: ConstructionException GTK+ fails to create the object. 206 */ 207 public this(GDateDay day, GDateMonth month, GDateYear year) 208 { 209 auto __p = g_date_new_dmy(day, month, year); 210 211 if(__p is null) 212 { 213 throw new ConstructionException("null returned by new_dmy"); 214 } 215 216 this(cast(GDate*) __p); 217 } 218 219 /** 220 * Like g_date_new(), but also sets the value of the date. Assuming the 221 * Julian day number you pass in is valid (greater than 0, less than an 222 * unreasonably large number), the returned date will be valid. 223 * 224 * Params: 225 * julianDay = days since January 1, Year 1 226 * 227 * Returns: a newly-allocated #GDate initialized with @julian_day 228 * 229 * Throws: ConstructionException GTK+ fails to create the object. 230 */ 231 public this(uint julianDay) 232 { 233 auto __p = g_date_new_julian(julianDay); 234 235 if(__p is null) 236 { 237 throw new ConstructionException("null returned by new_julian"); 238 } 239 240 this(cast(GDate*) __p); 241 } 242 243 /** 244 * Increments a date some number of days. 245 * To move forward by weeks, add weeks*7 days. 246 * The date must be valid. 247 * 248 * Params: 249 * nDays = number of days to move the date forward 250 */ 251 public void addDays(uint nDays) 252 { 253 g_date_add_days(gDate, nDays); 254 } 255 256 /** 257 * Increments a date by some number of months. 258 * If the day of the month is greater than 28, 259 * this routine may change the day of the month 260 * (because the destination month may not have 261 * the current day in it). The date must be valid. 262 * 263 * Params: 264 * nMonths = number of months to move forward 265 */ 266 public void addMonths(uint nMonths) 267 { 268 g_date_add_months(gDate, nMonths); 269 } 270 271 /** 272 * Increments a date by some number of years. 273 * If the date is February 29, and the destination 274 * year is not a leap year, the date will be changed 275 * to February 28. The date must be valid. 276 * 277 * Params: 278 * nYears = number of years to move forward 279 */ 280 public void addYears(uint nYears) 281 { 282 g_date_add_years(gDate, nYears); 283 } 284 285 /** 286 * If @date is prior to @min_date, sets @date equal to @min_date. 287 * If @date falls after @max_date, sets @date equal to @max_date. 288 * Otherwise, @date is unchanged. 289 * Either of @min_date and @max_date may be %NULL. 290 * All non-%NULL dates must be valid. 291 * 292 * Params: 293 * minDate = minimum accepted value for @date 294 * maxDate = maximum accepted value for @date 295 */ 296 public void clamp(Date minDate, Date maxDate) 297 { 298 g_date_clamp(gDate, (minDate is null) ? null : minDate.getDateStruct(), (maxDate is null) ? null : maxDate.getDateStruct()); 299 } 300 301 /** 302 * Initializes one or more #GDate structs to a safe but invalid 303 * state. The cleared dates will not represent an existing date, but will 304 * not contain garbage. Useful to init a date declared on the stack. 305 * Validity can be tested with g_date_valid(). 306 * 307 * Params: 308 * nDates = number of dates to clear 309 */ 310 public void clear(uint nDates) 311 { 312 g_date_clear(gDate, nDates); 313 } 314 315 /** 316 * qsort()-style comparison function for dates. 317 * Both dates must be valid. 318 * 319 * Params: 320 * rhs = second date to compare 321 * 322 * Returns: 0 for equal, less than zero if @lhs is less than @rhs, 323 * greater than zero if @lhs is greater than @rhs 324 */ 325 public int compare(Date rhs) 326 { 327 return g_date_compare(gDate, (rhs is null) ? null : rhs.getDateStruct()); 328 } 329 330 /** 331 * Copies a GDate to a newly-allocated GDate. If the input was invalid 332 * (as determined by g_date_valid()), the invalid state will be copied 333 * as is into the new object. 334 * 335 * Returns: a newly-allocated #GDate initialized from @date 336 * 337 * Since: 2.56 338 */ 339 public Date copy() 340 { 341 auto __p = g_date_copy(gDate); 342 343 if(__p is null) 344 { 345 return null; 346 } 347 348 return new Date(cast(GDate*) __p, true); 349 } 350 351 /** 352 * Computes the number of days between two dates. 353 * If @date2 is prior to @date1, the returned value is negative. 354 * Both dates must be valid. 355 * 356 * Params: 357 * date2 = the second date 358 * 359 * Returns: the number of days between @date1 and @date2 360 */ 361 public int daysBetween(Date date2) 362 { 363 return g_date_days_between(gDate, (date2 is null) ? null : date2.getDateStruct()); 364 } 365 366 /** 367 * Frees a #GDate returned from g_date_new(). 368 */ 369 public void free() 370 { 371 g_date_free(gDate); 372 ownedRef = false; 373 } 374 375 /** 376 * Returns the day of the month. The date must be valid. 377 * 378 * Returns: day of the month 379 */ 380 public GDateDay getDay() 381 { 382 return g_date_get_day(gDate); 383 } 384 385 /** 386 * Returns the day of the year, where Jan 1 is the first day of the 387 * year. The date must be valid. 388 * 389 * Returns: day of the year 390 */ 391 public uint getDayOfYear() 392 { 393 return g_date_get_day_of_year(gDate); 394 } 395 396 /** 397 * Returns the week of the year, where weeks are interpreted according 398 * to ISO 8601. 399 * 400 * Returns: ISO 8601 week number of the year. 401 * 402 * Since: 2.6 403 */ 404 public uint getIso8601WeekOfYear() 405 { 406 return g_date_get_iso8601_week_of_year(gDate); 407 } 408 409 /** 410 * Returns the Julian day or "serial number" of the #GDate. The 411 * Julian day is simply the number of days since January 1, Year 1; i.e., 412 * January 1, Year 1 is Julian day 1; January 2, Year 1 is Julian day 2, 413 * etc. The date must be valid. 414 * 415 * Returns: Julian day 416 */ 417 public uint getJulian() 418 { 419 return g_date_get_julian(gDate); 420 } 421 422 /** 423 * Returns the week of the year, where weeks are understood to start on 424 * Monday. If the date is before the first Monday of the year, return 0. 425 * The date must be valid. 426 * 427 * Returns: week of the year 428 */ 429 public uint getMondayWeekOfYear() 430 { 431 return g_date_get_monday_week_of_year(gDate); 432 } 433 434 /** 435 * Returns the month of the year. The date must be valid. 436 * 437 * Returns: month of the year as a #GDateMonth 438 */ 439 public GDateMonth getMonth() 440 { 441 return g_date_get_month(gDate); 442 } 443 444 /** 445 * Returns the week of the year during which this date falls, if 446 * weeks are understood to begin on Sunday. The date must be valid. 447 * Can return 0 if the day is before the first Sunday of the year. 448 * 449 * Returns: week number 450 */ 451 public uint getSundayWeekOfYear() 452 { 453 return g_date_get_sunday_week_of_year(gDate); 454 } 455 456 /** 457 * Returns the day of the week for a #GDate. The date must be valid. 458 * 459 * Returns: day of the week as a #GDateWeekday. 460 */ 461 public GDateWeekday getWeekday() 462 { 463 return g_date_get_weekday(gDate); 464 } 465 466 /** 467 * Returns the year of a #GDate. The date must be valid. 468 * 469 * Returns: year in which the date falls 470 */ 471 public GDateYear getYear() 472 { 473 return g_date_get_year(gDate); 474 } 475 476 /** 477 * Returns %TRUE if the date is on the first of a month. 478 * The date must be valid. 479 * 480 * Returns: %TRUE if the date is the first of the month 481 */ 482 public bool isFirstOfMonth() 483 { 484 return g_date_is_first_of_month(gDate) != 0; 485 } 486 487 /** 488 * Returns %TRUE if the date is the last day of the month. 489 * The date must be valid. 490 * 491 * Returns: %TRUE if the date is the last day of the month 492 */ 493 public bool isLastOfMonth() 494 { 495 return g_date_is_last_of_month(gDate) != 0; 496 } 497 498 /** 499 * Checks if @date1 is less than or equal to @date2, 500 * and swap the values if this is not the case. 501 * 502 * Params: 503 * date2 = the second date 504 */ 505 public void order(Date date2) 506 { 507 g_date_order(gDate, (date2 is null) ? null : date2.getDateStruct()); 508 } 509 510 /** 511 * Sets the day of the month for a #GDate. If the resulting 512 * day-month-year triplet is invalid, the date will be invalid. 513 * 514 * Params: 515 * day = day to set 516 */ 517 public void setDay(GDateDay day) 518 { 519 g_date_set_day(gDate, day); 520 } 521 522 /** 523 * Sets the value of a #GDate from a day, month, and year. 524 * The day-month-year triplet must be valid; if you aren't 525 * sure it is, call g_date_valid_dmy() to check before you 526 * set it. 527 * 528 * Params: 529 * day = day 530 * month = month 531 * y = year 532 */ 533 public void setDmy(GDateDay day, GDateMonth month, GDateYear y) 534 { 535 g_date_set_dmy(gDate, day, month, y); 536 } 537 538 /** 539 * Sets the value of a #GDate from a Julian day number. 540 * 541 * Params: 542 * julianDate = Julian day number (days since January 1, Year 1) 543 */ 544 public void setJulian(uint julianDate) 545 { 546 g_date_set_julian(gDate, julianDate); 547 } 548 549 /** 550 * Sets the month of the year for a #GDate. If the resulting 551 * day-month-year triplet is invalid, the date will be invalid. 552 * 553 * Params: 554 * month = month to set 555 */ 556 public void setMonth(GDateMonth month) 557 { 558 g_date_set_month(gDate, month); 559 } 560 561 /** 562 * Parses a user-inputted string @str, and try to figure out what date it 563 * represents, taking the [current locale][setlocale] into account. If the 564 * string is successfully parsed, the date will be valid after the call. 565 * Otherwise, it will be invalid. You should check using g_date_valid() 566 * to see whether the parsing succeeded. 567 * 568 * This function is not appropriate for file formats and the like; it 569 * isn't very precise, and its exact behavior varies with the locale. 570 * It's intended to be a heuristic routine that guesses what the user 571 * means by a given string (and it does work pretty well in that 572 * capacity). 573 * 574 * Params: 575 * str = string to parse 576 */ 577 public void setParse(string str) 578 { 579 g_date_set_parse(gDate, Str.toStringz(str)); 580 } 581 582 /** 583 * Sets the value of a date from a #GTime value. 584 * The time to date conversion is done using the user's current timezone. 585 * 586 * Deprecated: Use g_date_set_time_t() instead. 587 * 588 * Params: 589 * time = #GTime value to set. 590 */ 591 public void setTime(GTime time) 592 { 593 g_date_set_time(gDate, time); 594 } 595 596 /** 597 * Sets the value of a date to the date corresponding to a time 598 * specified as a time_t. The time to date conversion is done using 599 * the user's current timezone. 600 * 601 * To set the value of a date to the current day, you could write: 602 * |[<!-- language="C" --> 603 * time_t now = time (NULL); 604 * if (now == (time_t) -1) 605 * // handle the error 606 * g_date_set_time_t (date, now); 607 * ]| 608 * 609 * Params: 610 * timet = time_t value to set 611 * 612 * Since: 2.10 613 */ 614 public void set_time_t(uint timet) 615 { 616 g_date_set_time_t(gDate, timet); 617 } 618 619 /** 620 * Sets the value of a date from a #GTimeVal value. Note that the 621 * @tv_usec member is ignored, because #GDate can't make use of the 622 * additional precision. 623 * 624 * The time to date conversion is done using the user's current timezone. 625 * 626 * Deprecated: #GTimeVal is not year-2038-safe. Use g_date_set_time_t() 627 * instead. 628 * 629 * Params: 630 * timeval = #GTimeVal value to set 631 * 632 * Since: 2.10 633 */ 634 public void setTimeVal(TimeVal timeval) 635 { 636 g_date_set_time_val(gDate, (timeval is null) ? null : timeval.getTimeValStruct()); 637 } 638 639 /** 640 * Sets the year for a #GDate. If the resulting day-month-year 641 * triplet is invalid, the date will be invalid. 642 * 643 * Params: 644 * year = year to set 645 */ 646 public void setYear(GDateYear year) 647 { 648 g_date_set_year(gDate, year); 649 } 650 651 /** 652 * Moves a date some number of days into the past. 653 * To move by weeks, just move by weeks*7 days. 654 * The date must be valid. 655 * 656 * Params: 657 * nDays = number of days to move 658 */ 659 public void subtractDays(uint nDays) 660 { 661 g_date_subtract_days(gDate, nDays); 662 } 663 664 /** 665 * Moves a date some number of months into the past. 666 * If the current day of the month doesn't exist in 667 * the destination month, the day of the month 668 * may change. The date must be valid. 669 * 670 * Params: 671 * nMonths = number of months to move 672 */ 673 public void subtractMonths(uint nMonths) 674 { 675 g_date_subtract_months(gDate, nMonths); 676 } 677 678 /** 679 * Moves a date some number of years into the past. 680 * If the current day doesn't exist in the destination 681 * year (i.e. it's February 29 and you move to a non-leap-year) 682 * then the day is changed to February 29. The date 683 * must be valid. 684 * 685 * Params: 686 * nYears = number of years to move 687 */ 688 public void subtractYears(uint nYears) 689 { 690 g_date_subtract_years(gDate, nYears); 691 } 692 693 /** 694 * Fills in the date-related bits of a struct tm using the @date value. 695 * Initializes the non-date parts with something safe but meaningless. 696 * 697 * Params: 698 * tm = struct tm to fill 699 */ 700 public void toStructTm(void* tm) 701 { 702 g_date_to_struct_tm(gDate, tm); 703 } 704 705 /** 706 * Returns %TRUE if the #GDate represents an existing day. The date must not 707 * contain garbage; it should have been initialized with g_date_clear() 708 * if it wasn't allocated by one of the g_date_new() variants. 709 * 710 * Returns: Whether the date is valid 711 */ 712 public bool valid() 713 { 714 return g_date_valid(gDate) != 0; 715 } 716 717 /** 718 * Returns the number of days in a month, taking leap 719 * years into account. 720 * 721 * Params: 722 * month = month 723 * year = year 724 * 725 * Returns: number of days in @month during the @year 726 */ 727 public static ubyte getDaysInMonth(GDateMonth month, GDateYear year) 728 { 729 return g_date_get_days_in_month(month, year); 730 } 731 732 /** 733 * Returns the number of weeks in the year, where weeks 734 * are taken to start on Monday. Will be 52 or 53. The 735 * date must be valid. (Years always have 52 7-day periods, 736 * plus 1 or 2 extra days depending on whether it's a leap 737 * year. This function is basically telling you how many 738 * Mondays are in the year, i.e. there are 53 Mondays if 739 * one of the extra days happens to be a Monday.) 740 * 741 * Params: 742 * year = a year 743 * 744 * Returns: number of Mondays in the year 745 */ 746 public static ubyte getMondayWeeksInYear(GDateYear year) 747 { 748 return g_date_get_monday_weeks_in_year(year); 749 } 750 751 /** 752 * Returns the number of weeks in the year, where weeks 753 * are taken to start on Sunday. Will be 52 or 53. The 754 * date must be valid. (Years always have 52 7-day periods, 755 * plus 1 or 2 extra days depending on whether it's a leap 756 * year. This function is basically telling you how many 757 * Sundays are in the year, i.e. there are 53 Sundays if 758 * one of the extra days happens to be a Sunday.) 759 * 760 * Params: 761 * year = year to count weeks in 762 * 763 * Returns: the number of weeks in @year 764 */ 765 public static ubyte getSundayWeeksInYear(GDateYear year) 766 { 767 return g_date_get_sunday_weeks_in_year(year); 768 } 769 770 /** 771 * Returns %TRUE if the year is a leap year. 772 * 773 * For the purposes of this function, leap year is every year 774 * divisible by 4 unless that year is divisible by 100. If it 775 * is divisible by 100 it would be a leap year only if that year 776 * is also divisible by 400. 777 * 778 * Params: 779 * year = year to check 780 * 781 * Returns: %TRUE if the year is a leap year 782 */ 783 public static bool isLeapYear(GDateYear year) 784 { 785 return g_date_is_leap_year(year) != 0; 786 } 787 788 /** 789 * Generates a printed representation of the date, in a 790 * [locale][setlocale]-specific way. 791 * Works just like the platform's C library strftime() function, 792 * but only accepts date-related formats; time-related formats 793 * give undefined results. Date must be valid. Unlike strftime() 794 * (which uses the locale encoding), works on a UTF-8 format 795 * string and stores a UTF-8 result. 796 * 797 * This function does not provide any conversion specifiers in 798 * addition to those implemented by the platform's C library. 799 * For example, don't expect that using g_date_strftime() would 800 * make the \%F provided by the C99 strftime() work on Windows 801 * where the C library only complies to C89. 802 * 803 * Params: 804 * s = destination buffer 805 * slen = buffer size 806 * format = format string 807 * date = valid #GDate 808 * 809 * Returns: number of characters written to the buffer, or 0 the buffer was too small 810 */ 811 public static size_t strftime(string s, size_t slen, string format, Date date) 812 { 813 return g_date_strftime(Str.toStringz(s), slen, Str.toStringz(format), (date is null) ? null : date.getDateStruct()); 814 } 815 816 /** 817 * Returns %TRUE if the day of the month is valid (a day is valid if it's 818 * between 1 and 31 inclusive). 819 * 820 * Params: 821 * day = day to check 822 * 823 * Returns: %TRUE if the day is valid 824 */ 825 public static bool validDay(GDateDay day) 826 { 827 return g_date_valid_day(day) != 0; 828 } 829 830 /** 831 * Returns %TRUE if the day-month-year triplet forms a valid, existing day 832 * in the range of days #GDate understands (Year 1 or later, no more than 833 * a few thousand years in the future). 834 * 835 * Params: 836 * day = day 837 * month = month 838 * year = year 839 * 840 * Returns: %TRUE if the date is a valid one 841 */ 842 public static bool validDmy(GDateDay day, GDateMonth month, GDateYear year) 843 { 844 return g_date_valid_dmy(day, month, year) != 0; 845 } 846 847 /** 848 * Returns %TRUE if the Julian day is valid. Anything greater than zero 849 * is basically a valid Julian, though there is a 32-bit limit. 850 * 851 * Params: 852 * julianDate = Julian day to check 853 * 854 * Returns: %TRUE if the Julian day is valid 855 */ 856 public static bool validJulian(uint julianDate) 857 { 858 return g_date_valid_julian(julianDate) != 0; 859 } 860 861 /** 862 * Returns %TRUE if the month value is valid. The 12 #GDateMonth 863 * enumeration values are the only valid months. 864 * 865 * Params: 866 * month = month 867 * 868 * Returns: %TRUE if the month is valid 869 */ 870 public static bool validMonth(GDateMonth month) 871 { 872 return g_date_valid_month(month) != 0; 873 } 874 875 /** 876 * Returns %TRUE if the weekday is valid. The seven #GDateWeekday enumeration 877 * values are the only valid weekdays. 878 * 879 * Params: 880 * weekday = weekday 881 * 882 * Returns: %TRUE if the weekday is valid 883 */ 884 public static bool validWeekday(GDateWeekday weekday) 885 { 886 return g_date_valid_weekday(weekday) != 0; 887 } 888 889 /** 890 * Returns %TRUE if the year is valid. Any year greater than 0 is valid, 891 * though there is a 16-bit limit to what #GDate will understand. 892 * 893 * Params: 894 * year = year 895 * 896 * Returns: %TRUE if the year is valid 897 */ 898 public static bool validYear(GDateYear year) 899 { 900 return g_date_valid_year(year) != 0; 901 } 902 }