The Battle for Wesnoth  1.13.4+dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
strftime.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2016 by Andrius Silinskas <[email protected]>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 #include "strftime.hpp"
15 
16 #include "gettext.hpp"
17 #include "language.hpp"
18 
19 #include <string>
20 
21 namespace {
22 
23 const char *wday_abbr[] = {N_("Sun"), N_("Mon"), N_("Tue"), N_("Wed"),
24  N_("Thu"), N_("Fri"), N_("Sat")};
25 const char *wday_full[] = {N_("Sunday"), N_("Monday"), N_("Tuesday"),
26  N_("Wednesday"), N_("Thursday"), N_("Friday"), N_("Saturday")};
27 const char *mon_abbr[] = {N_("Jan"), N_("Feb"), N_("Mar"), N_("Apr"),
28  N_("abbrev^May"), N_("Jun"), N_("Jul"), N_("Aug"), N_("Sep"), N_("Oct"),
29  N_("Nov"), N_("Dec")};
30 const char *mon_full[] = {N_("January"), N_("February"), N_("March"),
31  N_("April"), N_("May"), N_("June"), N_("July"), N_("August"),
32  N_("September"), N_("October"), N_("November"), N_("December")};
33 
34 }
35 
36 static std::string reformat(const std::string& format, const std::tm* time,
37  bool locale_correct, bool ampm_supported)
38 {
39  if (locale_correct && ampm_supported) {
40  return format;
41  }
42 
43  std::string new_format;
44 
45  for (std::string::const_iterator it = format.begin(); it != format.end();
46  ++it) {
47 
48  if (*it == '%') {
49  ++it;
50 
51  if(it == format.end()) {
52  new_format += "%";
53  break;
54  }
55 
56  bool unrecognized = false;
57 
58  if (!locale_correct) {
59  switch (*it) {
60  case 'a': // abbreviated weekday name
61  new_format += (time->tm_wday < 0 || time->tm_wday > 6) ?
62  "?" : translation::sgettext(wday_abbr[time->tm_wday]);
63  continue;
64  case 'A': // full weekday name
65  new_format += (time->tm_wday < 0 || time->tm_wday > 6) ?
66  "?" : translation::sgettext(wday_full[time->tm_wday]);
67  continue;
68  case 'b': // abbreviated month name
69  case 'h':
70  new_format += (time->tm_mon < 0 || time->tm_mon > 11) ?
71  "?" : translation::sgettext(mon_abbr[time->tm_mon]);
72  continue;
73  case 'B': // full month name
74  new_format += (time->tm_mon < 0 || time->tm_mon > 11) ?
75  "?" : translation::sgettext(mon_full[time->tm_mon]);
76  continue;
77  case 'c': // date and time
78  new_format += reformat(_("%a %b %e %H:%M:%S %Y"), time,
79  locale_correct, ampm_supported);
80  continue;
81  case '+': // date and time
82  new_format += reformat(_("%a %d %b %Y %H:%M:%S %z"),
83  time, locale_correct, ampm_supported);
84  continue;
85  default:
86  unrecognized = true;
87  }
88  }
89 
90  if (!ampm_supported || !locale_correct) {
91  switch (*it) {
92  case 'p': // AM or PM designation
93  new_format += (time->tm_hour < 12 ? _("AM") : _("PM"));
94  continue;
95  case 'P': // am or pm designation
96  new_format += (time->tm_hour < 12 ? _("am") : _("pm"));
97  continue;
98  default:
99  unrecognized = true;
100  }
101  }
102 
103  // Unrecognized format specifiers should be left
104  // for std::strftime to deal with them.
105  if (unrecognized) {
106  new_format += "%";
107  }
108  }
109 
110  new_format += *it;
111  }
112 
113  return new_format;
114 }
115 
116 static bool locale_supports_ampm(const std::tm* time)
117 {
118  const unsigned buffer_size = 16;
119  char time_buffer[buffer_size] = {0};
120 
121  size_t ret = std::strftime(time_buffer, buffer_size, "%p", time);
122 
123  if (ret == 0) {
124  return false;
125  }
126 
127  return true;
128 }
129 
130 namespace util {
131 
132 size_t strftime(char* str, size_t count, const std::string& format,
133  const std::tm* time)
134 {
135  bool ampm_supported = locale_supports_ampm(time);
136  const std::string f = reformat(format, time, time_locale_correct(),
137  ampm_supported);
138 
139  return std::strftime(str, count, f.c_str(), time);
140 }
141 
142 } // end namespace util
bool & time_locale_correct()
Definition: language.cpp:67
size_t strftime(char *str, size_t count, const std::string &format, const std::tm *time)
Definition: strftime.cpp:132
static bool locale_supports_ampm(const std::tm *time)
Definition: strftime.cpp:116
static std::string reformat(const std::string &format, const std::tm *time, bool locale_correct, bool ampm_supported)
Definition: strftime.cpp:36
static UNUSEDNOWARN std::string _(const char *str)
Definition: gettext.hpp:82
GLuint GLuint GLsizei count
Definition: glew.h:1221
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: glew.h:1222
#define N_(String)
Definition: gettext.hpp:90
static UNUSEDNOWARN std::string sgettext(const char *str)
Definition: gettext.hpp:66
GLsizei const GLcharARB ** string
Definition: glew.h:4503
GLclampf f
Definition: glew.h:3024