logo

utils

~/.local/bin tools and git-hooks git clone https://hacktivis.me/git/utils.git

date.c (1946B)


  1. // Collection of Unix tools, comparable to coreutils
  2. // SPDX-FileCopyrightText: 2017-2022 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _POSIX_C_SOURCE 200809L
  5. #include "../lib/iso_parse.h" /* iso_parse */
  6. #include <errno.h> /* errno */
  7. #include <locale.h> /* setlocale() */
  8. #include <stdio.h> /* BUFSIZ, perror(), puts() */
  9. #include <stdlib.h> /* exit(), strtol() */
  10. #include <time.h> /* time, localtime, tm, strftime */
  11. #include <unistd.h> /* getopt(), optarg, optind */
  12. void
  13. usage()
  14. {
  15. fprintf(stderr, "date [-uR][-d datetime] [+format]\n");
  16. }
  17. int
  18. main(int argc, char *argv[])
  19. {
  20. char outstr[BUFSIZ];
  21. struct tm *tm;
  22. time_t now;
  23. char *format = "%c";
  24. int uflag = 0;
  25. int c;
  26. setlocale(LC_ALL, "");
  27. now = time(NULL);
  28. if(now == (time_t)-1)
  29. {
  30. perror("date: time");
  31. exit(EXIT_FAILURE);
  32. }
  33. while((c = getopt(argc, argv, ":d:uR")) != -1)
  34. {
  35. switch(c)
  36. {
  37. case 'd': /* Custom datetime */
  38. now = iso_parse(optarg).tv_sec;
  39. break;
  40. case 'u': /* UTC timezone */
  41. uflag++;
  42. break;
  43. case 'R': /* Email (RFC 5322) format */
  44. format = "%a, %d %b %Y %H:%M:%S %z";
  45. break;
  46. case ':':
  47. fprintf(stderr, "date: Error: Missing operand for option: '-%c'\n", optopt);
  48. usage();
  49. return 1;
  50. case '?':
  51. fprintf(stderr, "date: Error: Unrecognised option: '-%c'\n", optopt);
  52. usage();
  53. return 1;
  54. }
  55. }
  56. if(uflag)
  57. {
  58. tm = gmtime(&now);
  59. if(tm == NULL)
  60. {
  61. perror("date: gmtime");
  62. exit(EXIT_FAILURE);
  63. }
  64. }
  65. else
  66. {
  67. tm = localtime(&now);
  68. if(tm == NULL)
  69. {
  70. perror("date: localtime");
  71. exit(EXIT_FAILURE);
  72. }
  73. }
  74. argc -= optind;
  75. argv += optind;
  76. (void)argc;
  77. if(*argv && **argv == '+') format = *argv + 1;
  78. errno = 0;
  79. if(strftime(outstr, sizeof(outstr), format, tm) == 0 && errno != 0)
  80. {
  81. perror("date: strftime");
  82. exit(EXIT_FAILURE);
  83. }
  84. if(puts(outstr) < 0)
  85. {
  86. perror("date: puts");
  87. exit(EXIT_FAILURE);
  88. }
  89. return 0;
  90. }