web-dev-qa-db-fra.com

Date et horodatage Java à partir de l'instance de ZonedDateTime UTC

J'ai une application Java dans laquelle je voudrais l'heure en UTC. Actuellement, le code utilise une combinaison de Java.util.Date et Java.sql.Timestamp. Pour obtenir l'heure en UTC, le programmeur avant moi a utilisé:

Pour Date:

 Date.from(ZonedDateTime.now(ZoneOffset.UTC)).toInstant();

Pour l'horodatage:

 Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());

Cependant, j'ai moi-même effectué plusieurs tests avec ce code et ces deux lignes renvoient la date et l'heure actuelles (dans mon fuseau horaire actuel). D'après tout ce que j'ai lu apparaît que Date/Timestamp n'a pas de valeur zoneOffset, mais je ne trouve pas d'énoncé concret à ce sujet.

Est-il possible de conserver l'heure (UTC) dans les objets Date ou Timestamp ou dois-je refactoriser et utiliser le véritable objet ZonedDateTime dans mon application? Cet objet ZonedateTime sera-t-il également compatible avec l’objet Timestamp actuel pour SQL?

Exemple:

public static void main (String args[])
{
    ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
    Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
    Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
    System.out.println("ZonedDateTime: " + zonedDateTime);
    System.out.println("Timestamp: " + timestamp);
    System.out.println("Date: " + date);
}

Sortie: 

 ZonedDateTime: 2017-04-06T15:46:33.099Z
 Timestamp: 2017-04-06 10:46:33.109
 Date: Thu Apr 06 10:46:33 CDT 2017
15

En Java, Date représente un point dans le temps. Ce n'est pas lié à l'horodatage. Lorsque vous appelez la méthode toString() d'un objet Date, il convertit cette heure en horodatage par défaut de Platform, par exemple. Ce qui suit imprimera la date/heure en UTC (car il définit le fuseau horaire par défaut sur UTC):

TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneOffset.UTC);
Timestamp timestamp = Timestamp.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
Date date = Date.from(ZonedDateTime.now(ZoneOffset.UTC).toInstant());
System.out.println("ZonedDateTime: " + zonedDateTime);
System.out.println("Timestamp: " + timestamp);
System.out.println("Date: " + date);
5
Darshan Mehta

J'ai créé la classe SimpleJdbcUpdate illustrée ci-dessous:

public class SimpleJdbcUpdate {

private final JdbcTemplate jdbcTemplate;
private DataSource dataSource;
private String tableName;
private final TableMetaDataContext tableMetaDataContext = new TableMetaDataContext();
Map<String, ColumnInfo> propertyToColumnMap = new HashMap<>();
private boolean compiled;

public SimpleJdbcUpdate(DataSource dataSource) {
    jdbcTemplate = new JdbcTemplate(dataSource);
    this.dataSource = dataSource;
}

private List<String> getColumnNames() {
    return Collections.emptyList();
}

private String[] getGeneratedKeyNames() {
    return new String[0];
}

public SimpleJdbcUpdate withTableName(String tableName) {
    this.tableName = tableName;
    return this;
}

public int execute(BeanPropertySqlParameterSource parameterSource, String[] keys) {

    if (!compiled) {
        compile();
    }

    return doExecute(parameterSource, keys);
}

private int doExecute(BeanPropertySqlParameterSource parameterSource, String[] keys) {
    String[] propertyNames = parameterSource.getParameterNames();

    List<Object> values = new ArrayList<>();
    String updateSql = updateSql(parameterSource, propertyNames, values);
    String wherePart = wherePart(parameterSource, keys, values);

    String updateSqlWithWhere = updateSql + wherePart;
    return jdbcTemplate.update(updateSqlWithWhere, values.toArray());
}

private String updateSql(BeanPropertySqlParameterSource parameterSource, String[] propertyNames, List<Object> values) {
    StringBuilder updateSqlBuilder = new StringBuilder("update " + tableName + " set ");
    boolean first = true;
    for (String propertyName : propertyNames) {
        ColumnInfo columnInfo = propertyToColumnMap.get(propertyName);
        if (columnInfo == null) {
            continue;
        }

        addValue(parameterSource, values, propertyName);

        if (!first) {
            updateSqlBuilder.append(", ");
        }
        updateSqlBuilder.append(columnInfo.columnName + " = ?");
        first = false;
    }
    return updateSqlBuilder.toString();
}

private String wherePart(BeanPropertySqlParameterSource parameterSource, String[] keys, List<Object> values) {
    StringBuilder wherePartBuilder = new StringBuilder();
    boolean first = true;
    for (String key : keys) {
        ColumnInfo columnInfo = propertyToColumnMap.get(key);
        if (columnInfo == null) {
            continue;
        }

        addValue(parameterSource, values, key);

        if (first) {
            wherePartBuilder.append(" WHERE ");
        } else {
            wherePartBuilder.append(" AND ");
        }
        wherePartBuilder.append(columnInfo.columnName + " = ?");

        first = false;
    }
    return wherePartBuilder.toString();
}

private void addValue(BeanPropertySqlParameterSource parameterSource, List<Object> values, String propertyName) {
    if (parameterSource.hasValue(propertyName)) {
        Object typedValue = SqlParameterSourceUtils.getTypedValue(parameterSource, propertyName);
        if (typedValue.getClass().isEnum()) {
            typedValue = new SqlParameterValue(Types.VARCHAR, ((Enum) typedValue).name());
        }
        values.add(typedValue);
    }
}

private void compile() {
    tableMetaDataContext.setTableName(tableName);
    this.tableMetaDataContext.processMetaData(dataSource, getColumnNames(), getGeneratedKeyNames());

    List<String> tableColumns = tableMetaDataContext.getTableColumns();
    for (int i = 0; i < tableColumns.size(); i++) {
        String column = tableColumns.get(i);
        String propertyName = JdbcUtils.convertUnderscoreNameToPropertyName(column);
        propertyToColumnMap.put(propertyName, new ColumnInfo(column, i));
    }

    compiled = true;
}

private static class ColumnInfo {
    String columnName;
    Integer index;

    public ColumnInfo(String columnName, Integer index) {
        this.columnName = columnName;
        this.index = index;
    }
  }
}
0
Umesh Rajbhandari