Repository: minio/minio (language: go)

Issue:
Error in parsing response date
When creating a service account, if the expiration time is, for example, 2024-05-04T09:35:47.1<ins>**00**</ins>Z (or 2024-05-04T09:35:47.12<ins>**0**</ins>Z). Then minio truncates 0 in milliseconds in response and the converter cannot parse the date, since the pattern requires 3 fraction-of-second (["yyyy-MM-dd'T'HH':'mm':'ss'.'<ins>**SSS**</ins>'Z'"](https://github.com/minio/minio-java/blob/8.5.10/api/src/main/java/io/minio/Time.java#L32))

Stacktrace: 
```
Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `io.minio.messages.ResponseDate`, problem: Text '2024-05-04T09:35:47.1Z' could not be parsed at index 19
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 120] (through reference chain: io.minio.admin.AddServiceAccountResp["credentials"]->io.minio.credentials.Credentials["expiration"])
	... 15 more
Caused by: com.fasterxml.jackson.databind.exc.ValueInstantiationException: Cannot construct instance of `io.minio.messages.ResponseDate`, problem: Text '2024-05-04T09:35:47.1Z' could not be parsed at index 19
 at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 120] (through reference chain: io.minio.admin.AddServiceAccountResp["credentials"]->io.minio.credentials.Credentials["expiration"])
	at com.fasterxml.jackson.databind.exc.ValueInstantiationException.from(ValueInstantiationException.java:47)
	at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:2014)
	at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.wrapAsJsonMappingException(StdValueInstantiator.java:598)
	at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.rewrapCtorProblem(StdValueInstantiator.java:621)
	at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:346)
	at com.fasterxml.jackson.databind.deser.std.StdDeserializer._deserializeFromString(StdDeserializer.java:265)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1588)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:197)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
	at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:545)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:570)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:440)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1493)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
	at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4899)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3907)
	at io.minio.admin.MinioAdminClient.addServiceAccount(MinioAdminClient.java:693)
	... 90 more
Caused by: java.time.format.DateTimeParseException: Text '2024-05-04T09:35:47.1Z' could not be parsed at index 19
	at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2052)
	at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954)
	at java.base/java.time.ZonedDateTime.parse(ZonedDateTime.java:600)
	at io.minio.messages.ResponseDate.fromString(ResponseDate.java:59)
	at jdk.internal.reflect.GeneratedMethodAccessor26.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at com.fasterxml.jackson.databind.introspect.AnnotatedMethod.call1(AnnotatedMethod.java:110)
	at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:343)
	... 108 more
```


Discussion / hints:
As per the format, '2024-05-04T09:35:47.1Z' is invalid, the parse error is thrown. Please check your server.
@balamurugana, minio (RELEASE.2024-01-16T16-07-38Z) returns the date in this format
@balamurugana Go truncates by removing the trailing 00's. It is not strictly needed; this is similar to retention date parsing AFAICS.

@harshavardhana expiration is [ResponseDate](https://github.com/minio/minio-java/blob/master/api/src/main/java/io/minio/messages/ResponseDate.java) type and we are already taking care of two formats 
```java
  public static final DateTimeFormatter RESPONSE_DATE_FORMAT =
      DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH':'mm':'ss'.'SSS'Z'", Locale.US).withZone(UTC);
```
```java
  public static final DateTimeFormatter MINIO_RESPONSE_DATE_FORMAT =
      DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH':'mm':'ss'Z'", Locale.US).withZone(Time.UTC);
```

Previously we faced the same issue from the server and the server got fixed.

Fix patch:
diff --git a/cmd/admin-handlers-users.go b/cmd/admin-handlers-users.go
index b7b76e0c293f2..b37931400c199 100644
--- a/cmd/admin-handlers-users.go
+++ b/cmd/admin-handlers-users.go
@@ -2476,6 +2476,12 @@ func commonAddServiceAccount(r *http.Request) (context.Context, auth.Credentials
 		return ctx, auth.Credentials{}, newServiceAccountOpts{}, madmin.AddServiceAccountReq{}, "", errorCodes.ToAPIErrWithErr(ErrAdminConfigBadJSON, err)
 	}
 
+	if createReq.Expiration != nil && !createReq.Expiration.IsZero() {
+		// truncate expiration at the second.
+		truncateTime := createReq.Expiration.Truncate(time.Second)
+		createReq.Expiration = &truncateTime
+	}
+
 	// service account access key cannot have space characters beginning and end of the string.
 	if hasSpaceBE(createReq.AccessKey) {
 		return ctx, auth.Credentials{}, newServiceAccountOpts{}, madmin.AddServiceAccountReq{}, "", errorCodes.ToAPIErr(ErrAdminResourceInvalidArgument)


Test patch: