I search for a pattern which looks like this: Thu, 11. 05. 1999
So I tried this syntax:
String pattern = "DDD, dd. mm. uuuu";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
But it won't work. When trying to format a LocalDate I get java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: MinuteOfHour.
A look into the official documentation of Java explaining the format pattern syntax is always good:
E = day-of-week
M = month
m = minute
So you should try this pattern:
EEE, dd. MM. uuuu
And setting the locale explicitly to English is also a good idea.
Related
hi I has date format and I want converted to correct GMT date :
<YYMMDDhhmmssNNN><C|D|G|H>
Sample value on that date:
210204215026000C
I get this explanation for part NNN :
NNN If flag is C or D then NNN is the number of hours relativeto GMT,
if flag is G or H, NNN is the number of quarter hours relative to GMT
C|D|G|H C and G = Ahead of GMT, D and H = Behind GMT
but I did not get how number of hours relative to GMT can present on 3 digits ? it should be in 2 digit as i knew the offset for hours related to GMT is from 0 to 23 , and also what quarter hours relative to GMT mean ?
I want to use Scala or Java.
I don’t know why they set 3 digits aside for the offset. I agree with you that 2 digits suffice for all cases. Maybe they just wanted to be very sure they would never run of out space, and maybe they even overdid this a bit. 3 digits is not a problem as long as the actual values are within the range that java.time.ZoneOffset can handle, +/-18 hours. In your example NNN is 000, so 0 hours from GMT, which certainly is OK and trivial to handle.
A quarter hour is a quarter of an hour. As Salman A mentioned in a comment, 22 quarter hours ahead of Greenwich means an offset of +05:30, currently used in Sri Lanka and India. If the producer of the string wants to use this option, they can give numbers up to 72 (still comfortably within 2 digits). 18 * 4 = 72, so 18 hours equals 72 quarter hours. To imagine a situation where 2 digits would be too little, think an offset of 25 hours. I wouldn’t think it realistic, on the other hand no one can guarantee that it will never happen.
Java solution: how to parse and convert to GMT time
I am using these constants:
private static final Pattern DATE_PATTERN
= Pattern.compile("(\\d{12})(\\d{3})(\\w)");
private static final DateTimeFormatter FORMATTER
= DateTimeFormatter.ofPattern("uuMMddHHmmss");
private static final int SECONDS_IN_A_QUARTER_HOUR
= Math.toIntExact(Duration.ofHours(1).dividedBy(4).getSeconds());
Parse and convert like this:
String sampleValue = "210204215026000C";
Matcher matcher = DATE_PATTERN.matcher(sampleValue);
if (matcher.matches()) {
LocalDateTime ldt = LocalDateTime.parse(matcher.group(1), FORMATTER);
int offsetAmount = Integer.parseInt(matcher.group(2));
char flag = matcher.group(3).charAt(0);
// offset amount denotes either hours or quarter hours
boolean quarterHours = flag == 'G' || flag == 'H';
boolean negative = flag == 'D' || flag == 'H';
if (negative) {
offsetAmount = -offsetAmount;
}
ZoneOffset offset = quarterHours
? ZoneOffset.ofTotalSeconds(offsetAmount * SECONDS_IN_A_QUARTER_HOUR)
: ZoneOffset.ofHours(offsetAmount);
OffsetDateTime dateTime = ldt.atOffset(offset);
OffsetDateTime gmtDateTime = dateTime.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println("GMT time: " + gmtDateTime);
}
else {
System.out.println("Invalid value: " + sampleValue);
}
Output is:
GMT time: 2021-02-04T21:50:26Z
I think my code covers all valid cases. You will probably want to validate that the flag is indeed C, D, G or H, and also handle the potential DateTimeException and NumberFormatException from the parsing and creating the ZoneOffset (NumberFormatException should not happen).
I have a label in my asp.net web site that will shows the time. I want the output like here. in the morning like this: 08:26 and after 12 am,it shows 15:28
My code does not work. It only supports the first part.
DateTime tim = DateTime.Now;
int hh = p.GetHour(tim);
int mm = p.GetMinute(tim);
Label7.Text = DateTime.Now.ToString("hh:mm");
According to the Custom date and time format strings docs page - you can see:
"hh" The hour, using a 12-hour clock from 01 to 12.
"HH" The hour, using a 24-hour clock from 00 to 23.
So in your case - just use the capitalized HH for your formatting:
Label7.Text = DateTime.Now.ToString("HH:mm");
and you should get what you're looking for.
Our Rest API is used by several external parties. They all use "ISO-ish" formats, but the formatting of the time zone offset is slightly different. These are some of the most common formats we see:
2018-01-01T15:56:31.410Z
2018-01-01T15:56:31.41Z
2018-01-01T15:56:31Z
2018-01-01T15:56:31+00:00
2018-01-01T15:56:31+0000
2018-01-01T15:56:31+00
In my controller I use the following annotations:
#RequestMapping(value = ["/some/api/call"], method = [GET])
fun someApiCall(
#RequestParam("from")
#DateTimeFormat(iso = ISO.DATE_TIME)
from: OffsetDateTime
) {
...
}
It parses variant 1-4 just fine but produces a 400 Bad Request error for variants 5 and 6 with the following exception:
Caused by: java.time.format.DateTimeParseException: Text '2018-01-01T13:37:00.001+00' could not be parsed, unparsed text found at index 23
at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1952)
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
How can I make it accept all the above ISO formatting variants (even if they are not 100% compliant to the ISO standard)?
I solved it by adding a custom formatter annotation:
#Target(AnnotationTarget.VALUE_PARAMETER)
#Retention(AnnotationRetention.RUNTIME)
annotation class IsoDateTime
Plus a FormatterFactory:
class DefensiveDateTimeFormatterFactory :
EmbeddedValueResolutionSupport(), AnnotationFormatterFactory<IsoDateTime>
{
override fun getParser(annotation: IsoDateTime?, fieldType: Class<*>?): Parser<*> {
return Parser<OffsetDateTime> { text, _ -> OffsetDateTime.parse(text, JacksonConfig.defensiveFormatter) }
}
override fun getPrinter(annotation: IsoDateTime, fieldType: Class<*>): Printer<*> {
return Printer<OffsetDateTime> { obj, _ -> obj.format(DateTimeFormatter.ISO_DATE_TIME) }
}
override fun getFieldTypes(): MutableSet<Class<*>> {
return mutableSetOf(OffsetDateTime::class.java)
}
}
The actual DateTimeFormat class comes from my other question, How to parse different ISO date/time formats with Jackson and java.time?
And added it to Spring using WebMvcConfigurer:
#Configuration
open class WebMvcConfiguration : WebMvcConfigurer {
override fun addFormatters(registry: FormatterRegistry) {
registry.addFormatterForFieldAnnotation(DefensiveDateTimeFormatterFactory())
}
}
You get 400-Bad Request because format 5 and 6 are not part of the ISO specifications.
If you look at the Time Zone Designator, it can be one of Z or +hh:mm or -hh:mm.
The official list of ISO-8601 formats can be found here.
Year:
YYYY (eg 1997)
Year and month:
YYYY-MM (eg 1997-07)
Complete date:
YYYY-MM-DD (eg 1997-07-16)
Complete date plus hours and minutes:
YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)
Complete date plus hours, minutes and seconds:
YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)
Complete date plus hours, minutes, seconds and a decimal fraction of a second
YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
where:
YYYY = four-digit year
MM = two-digit month (01=January, etc.)
DD = two-digit day of month (01 through 31)
hh = two digits of hour (00 through 23) (am/pm NOT allowed)
mm = two digits of minute (00 through 59)
ss = two digits of second (00 through 59)
s = one or more digits representing a decimal fraction of a second
TZD = time zone designator (Z or +hh:mm or -hh:mm)
I'm trying to convert the DATETIME to something that people can actually use. This is the date:
2013-09-05 11:52:10
I'm using:
date("D, d M Y", '2013-09-05 11:52:10');
Is turning into:
Thu, 01 Jan 1970
Makes no sense to me.
You need to turn the date into a timestamp before passing it to date()
$time = strtotime('2013-09-05 11:52:10');
echo date("D, d M Y", $time);
Is this supposed to be PHP code? If so, the correct is
date("D, d M Y", strtotime('2013-09-05 11:52:10'));
If this has to do with MySql, the correct function to use is DATE_FORMAT (however, what you have is invalid MySql syntax). Please clarify.
PHP's date() function can only handle integer timestamp values; it can't process strings as input.
If you need to convert from one string date format to another, you should use the DateTime::CreateFromFormat() method:
$dateObj = DateTime::CreateFromFormat($inputString);
$outputString = $dateObj->Format('D, d M Y');
However, I would recommend writing your query to use MySQL's UNIX_TIMESTAMP() function to get the date into PHP as a numeric timestamp that PHP's date() function can handle:
MySQL:
SELECT UNIX_TIMESTAMP(yourDateField) as yourDateField_timestamp FROM yourTable ...
Then you can write PHP exactly as you wanted:
PHP:
$dateObj = date('D, d M Y', $row['yourDateField_timestamp']);
I have got a string in the form:
8 AM;10:15 AM;3:30 PM;6:15 PM
which i need to format in the form
8 AM-10:15 AM, 3:30 PM-6:15 PM
How can i achieve this?
You could do string splitting on ;, like this
var parts = s.Split(";".ToCharArray());
Then you could use the parts, like this:
var result = string.Format("{0}-{1}, {2}-{3}", parts);
This requires that the string always contains 4 parts.