facilitare la sostituzione ed data oggetto con “oggi” e archi “ieri” nel metodo statico Java

StackOverflow https://stackoverflow.com/questions/4292139

  •  28-09-2019
  •  | 
  •  

Domanda

Ho seguito il metodo che mi piacerebbe fare più breve o più veloce se non altro. Si prega tutti i commenti sono benvenuti:

metodo Bellow prende un oggetto data, formiati IT ( "hh EEE: mma MMM d, yyyy") e poi capisce se la data è oggi o ieri e che, se lo è, esso restituisce "(Oggi | Oggi) hh:. mma" formattato stringa

    public static String formatToYesterdayOrToday(String date) {
    SimpleDateFormat sdf = new SimpleDateFormat("EEE hh:mma MMM d, yyyy");
    Date in = null;

    try {
        in = sdf.parse(date);
    } catch (ParseException e) {
        log.debug("Date parsing error:", e);
    }

    Calendar x = Calendar.getInstance();
    x.setTime(in);

    String hour = Integer.toString(x.get(Calendar.HOUR));
    String minute = Integer.toString(x.get(Calendar.MINUTE));
    String pm_am = x.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM";

    x.set(Calendar.HOUR, 0);
    x.set(Calendar.HOUR_OF_DAY, 0);
    x.set(Calendar.MINUTE, 0);
    x.set(Calendar.SECOND, 0);
    x.set(Calendar.MILLISECOND, 0);

    Calendar today = Calendar.getInstance();
    today.set(Calendar.HOUR, 0);
    today.set(Calendar.HOUR_OF_DAY, 0);
    today.set(Calendar.MINUTE, 0);
    today.set(Calendar.SECOND, 0);
    today.set(Calendar.MILLISECOND, 0);

    Calendar yesterday = Calendar.getInstance();
    yesterday.set(Calendar.HOUR, 0);
    yesterday.set(Calendar.HOUR_OF_DAY, 0);
    yesterday.set(Calendar.MINUTE, 0);
    yesterday.set(Calendar.SECOND, 0);
    yesterday.set(Calendar.MILLISECOND, 0);
    yesterday.add(Calendar.DATE, -1);

    if (x.compareTo(today) == 0) {
        return "Today " + hour + ":" + minute + pm_am;
    }
    if (x.compareTo(yesterday) == 0) {
        return "Yesterday " + hour + ":" + minute + pm_am;
    }
    return date;
}
È stato utile?

Soluzione

Ecco come si potrebbe migliorare con l'API standard:

public static String formatToYesterdayOrToday(String date) throws ParseException {
    Date dateTime = new SimpleDateFormat("EEE hh:mma MMM d, yyyy").parse(date);
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(dateTime);
    Calendar today = Calendar.getInstance();
    Calendar yesterday = Calendar.getInstance();
    yesterday.add(Calendar.DATE, -1);
    DateFormat timeFormatter = new SimpleDateFormat("hh:mma");

    if (calendar.get(Calendar.YEAR) == today.get(Calendar.YEAR) && calendar.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR)) {
        return "Today " + timeFormatter.format(dateTime);
    } else if (calendar.get(Calendar.YEAR) == yesterday.get(Calendar.YEAR) && calendar.get(Calendar.DAY_OF_YEAR) == yesterday.get(Calendar.DAY_OF_YEAR)) {
        return "Yesterday " + timeFormatter.format(dateTime);
    } else {
        return date;
    }
}

Ecco come si potrebbe fare con Jodatime :

public static String formatToYesterdayOrToday(String date) {
    DateTime dateTime = DateTimeFormat.forPattern("EEE hh:mma MMM d, yyyy").parseDateTime(date);
    DateTime today = new DateTime();
    DateTime yesterday = today.minusDays(1);
    DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("hh:mma");

    if (dateTime.toLocalDate().equals(today.toLocalDate())) {
        return "Today " + timeFormatter.print(dateTime);
    } else if (dateTime.toLocalDate().equals(yesterday.toLocalDate())) {
        return "Yesterday " + timeFormatter.print(dateTime);
    } else {
        return date;
    }
}

Altri suggerimenti

ha scritto "tutti i commenti benvenuti" ecco il mio modo utilizzando Joda-tempo. :)

Sono un fan di visualizzazione delle date e gli orari in modo breve e intelligente delle chiamate recenti di iPhone (simile a Google i messaggi d'onda). Questo è "hh: mm" se oggi, "ieri" o il nome del giorno della settimana se <7 giorni, altrimenti yyyy-MM-dd .

private static boolean isToday (DateTime dateTime) {
   DateMidnight today = new DateMidnight();
   return today.equals(dateTime.toDateMidnight());
}

private static boolean isYesterday (DateTime dateTime) {
   DateMidnight yesterday = (new DateMidnight()).minusDays(1);
   return yesterday.equals(dateTime.toDateMidnight());
}

private static String getDayString(Date date) {
    String s;

    if (isToday(new DateTime(date)))
        s = "Today";
    else if (isYesterday(new DateTime(date)))
        s = "Yesterday";
    else
        s = weekdayFormat.format(date);

    return s;
}

public static String getDateString_shortAndSmart(Date date) {
    String s;

    DateTime nowDT = new DateTime();
    DateTime dateDT = new DateTime(date);
    int days = Days.daysBetween(dateDT, nowDT).getDays();

    if (isToday(new DateTime(date)))
        s = getHourMinuteString(date);
    else if (days < 7)
        s = getDayString(date);
    else
        s = getDateString(date);

    return s;
}

dove uso un insieme di SimpleDateFormat (come weekdayFormat sopra) per formattare il tempo per le corde desiderati, e dove DateTime e DateMidnight sono classi joda tempo.

In questi casi il numero di giorni trascorsi tra due DateTime: s è meno rilevante rispetto a come la gente avrebbe definire il tempo di parlarne. Invece di contare giorni (o millisecondi come ho visto alcune persone) DateMidnight viene portata di mano qui, anche se altri metodi avrebbe funzionato altrettanto bene. :)

Un altro modo di confrontare le date a parte la risposta accettata sopra utilizzando java.util.Date.getTime () (nota: lungo dovrebbe essere usato al posto di int):

Date today=new Date();
Date dateObj=null;
long diff=0;
try{
    dateObj= formater1.parse(date);
    diff=(today.getTime()-dateObj.getTime())/(86400000);
}catch(Exception e){}
String days="TODAY";
if(diff==1){
    days = "YESTERDAY";
}else if(diff>1){
    days = String.valueOf(diff) + " " +"DAYS AGO";
}

<% = giorni%> sarebbe tornato:

  

Oggi

     

IERI

     

x giorni fa

la mia comprensione della questione è di fornire un metodo semplice per l'uscita di prodotti come la seguente:

Today at 20:00
Today at 20:30
Today at 21:00
Tomorrow at 06:45
Tomorrow at 07:00
Tomorrow at 08:15

il codice qui sotto lavorato per me, ma io sono nuovo di Android e forse altri potrebbero notare se il codice non è robusto. nel codice di seguito 'timeLong' è il momento dei miei eventi nel tempo all'epoca (millisecondi).

public String convertFromEpochTime (long timeLong) {
    long timeNow = System.currentTimeMillis();

    // get day in relative time
    CharSequence timeDayRelative;
    timeDayRelative = DateUtils.getRelativeTimeSpanString(timeLong, timeNow, DateUtils.DAY_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE);

    // get hour in 24 hour time
    Format hourFormatter = new SimpleDateFormat("HH:mm");
    String timeHour = hourFormatter.format(timeLong);

    // Log.d(DEBUG_TAG, "time of event: " + timeDayRelative + " at " + timeHour);

    String timeDayHour = timeDayRelative + " at "+ timeHour;

    return timeDayHour;
}

Fuso orario

La questione e le altre risposte ignorare la questione cruciale del fuso orario. Quella stringa di input è priva di qualsiasi fuso orario o offset da UTC-. In modo che stringa verrà analizzata pur assumendo rappresenta un data-ora nel fuso orario predefinito corrente del JVM. rischioso come (a) tale ipotesi può essere falsa, e (b) che di default può cambiare in qualsiasi momento, anche durante il di esecuzione.

Locale

La questione e le altre risposte ignorare un'altra questione cruciale: Locale . Il Locale determina il linguaggio umano utilizzato per tradurre il nome del giorno e il nome del mese a partire dalla stringa di input durante l'analisi (e di generazione).

Se non specificato corrente di default del JVM Locale verrà utilizzato per la traduzione. Proprio come con il fuso orario, di default del vostro JVM Locale può cambiare in qualsiasi momento, anche durante il runtime.

Meglio specificare la vostra desiderata / previsto Locale.

java.time

La questione e le altre risposte utilizzare le vecchie classi data-ora che hanno dimostrato di essere mal progettato e fastidioso. Java 8 e più tardi ha la java.time framework integrato le cui classi soppiantare quelli vecchi.

metodo di analizzare una stringa durante la generazione di una nuova stringa dovrebbe essere suddiviso in due metodi. Un metodo dovrebbe analizzare per ottenere gli oggetti data-ora. Il secondo dovrebbe prendere oggetti data-ora e generare l'output stringa desiderata. Poi ogni possono essere usati separatamente. E questo approccio ci porta lontano dal pensare di stringhe come valori di data e ora. Le stringhe sono rappresentazioni testuali di valori di data e ora. La logica di business dovrebbe concentrarsi sulla manipolazione quei valori di data e ora come oggetti, si concentra sulle stringhe.

Analisi

private ZonedDateTime parseLengthyString ( String input , ZoneId zoneId , Locale locale ) {
    // FIXME: Check for nulls.

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "EEE hh:mma MMM d, uuuu" );
    formatter = formatter.withZone ( zoneId );
    formatter = formatter.withLocale ( locale );
    ZonedDateTime zdt = null;
    try {
        zdt = ZonedDateTime.parse ( input , formatter );
    } catch ( DateTimeParseException e ) {
        // FIXME: handle exeption.
        System.out.println ( "ERROR - e: " + e );
    }
    return zdt; // FIXME: Check for null.
}

Generazione

Dato un ZonedDateTime in mano dal metodo di cui sopra, si può generare una rappresentazione testuale del suo valore data-ora utilizzando un oggetto Locale per la traduzione del nome-del-giorno e il nome-del-mese.

Per determinare se la data-ora è per oggi o ieri, ci interessa solo la parte di data senza l'ora del giorno. Per questo siamo in grado di utilizzare la href="http://docs.oracle.com/javase/8/docs/api/java/time/LocalDate.html" rel="nofollow"> LocalDate in classe java.time.

private String generateLengthyString ( ZonedDateTime zdt , Locale locale ) {
    // FIXME: Check for nulls.

    // Compare the date-only value of incoming date-time to date-only of today and yesterday.
    LocalDate localDateIncoming = zdt.toLocalDate ();

    Instant instant = Instant.now ();
    ZonedDateTime now = ZonedDateTime.now ( zdt.getZone () ); // Get current date-time in same zone as incoming ZonedDateTime.
    LocalDate localDateToday = now.toLocalDate ();
    LocalDate localDateYesterday = localDateToday.minusDays ( 1 );

    DateTimeFormatter formatter = null;
    if ( localDateIncoming.isEqual ( localDateToday ) ) {
        formatter = DateTimeFormatter.ofPattern ( "'Today' hh:mma" , locale ); // FIXME: Localize "Today".
    } else if ( localDateIncoming.isEqual ( localDateYesterday ) ) {
        formatter = DateTimeFormatter.ofPattern ( "'Yesterday' hh:mma" , locale ); // FIXME: Localize "Yesterday".
    } else {
        formatter = DateTimeFormatter.ofPattern ( "EEE hh:mma MMM d, uuuu" , locale );
    }

    String output = zdt.format ( formatter );
    return output; // FIXME: Check for null.
}

Esempio

Esercizio questi due metodi.

arbitrariamente di scegliere un fuso orario America/New_York come la questione non specifica.

String input = "Sat 11:23AM Feb 6, 2016";
ZoneId zoneId = ZoneId.of ( "America/New_York" );
Locale locale = Locale.US;
ZonedDateTime zdt = this.parseLengthyString ( input , zoneId , locale );

String output = this.generateLengthyString ( zdt , locale );

A proposito, si può chiedere java.time per formattare automaticamente la stringa di output secondo le norme culturali del Locale, invece di codificare un formato.

String outputPerLocale = zdt.format ( DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.MEDIUM ) );

Dump alla console.

System.out.println ( "input: " + input + " | zdt: " + zdt + " | Instant: " + zdt.toInstant () + " | output: " | output + " + outputPerLocale: " + outputPerLocale );
  

ingresso: sab 11:23 Feb 6, 2016 | zdt: 2016-02-06T11: 23-05: 00 [America / New_York] | Istantanea: 2016-02-06T16: 23: 00Z | Uscita: Oggi 11:23 | outputPerLocale: Feb 6, 2016 11:23:00

A proposito, vi consiglio di mettere uno spazio prima del AM o PM per una più facile lettura.

questo per oggi, ieri, domani

String formatDate(String fecha){

    String Rfecha=new String();
     SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
     //SimpleDateFormat formatter2 = new SimpleDateFormat("EEEE d MMM");
     SimpleDateFormat formatter2 = new SimpleDateFormat("E, d MMM ");
        try {
           Date hoy=new Date();

            Date date = formatter.parse(fecha);


            String pref="";
           Log.d("hoy long", ""+(hoy.getTime()/ (1000*60*60*24)));
           Log.d("date long", ""+ (date.getTime()/ (1000*60*60*24)));

           int ihoy=(int) (hoy.getTime()/ (1000*60*60*24));
           int idate=(int) (date.getTime()/ (1000*60*60*24));
           int dif=idate-ihoy;



           if(dif==0)
               pref="Today";
           if(dif==1)
               pref="Tomorrow";
           if(dif==-1)
               pref="Yesterday";

            Rfecha=pref+" "+formatter2.format(date);


        } catch (Exception e) {
            e.printStackTrace();
        }

    return Rfecha;
}

Guarda jodatime: http://joda-time.sourceforge.net/

Questo è un codice ad esempio dal documento:

public boolean isAfterPayDay(DateTime datetime) {
  if (datetime.getMonthOfYear() == 2) {   // February is month 2!!
    return datetime.getDayOfMonth() > 26;
  }
  return datetime.getDayOfMonth() > 28;
}

public Days daysToNewYear(LocalDate fromDate) {
  LocalDate newYear = fromDate.plusYears(1).withDayOfYear(1);
  return Days.daysBetween(fromDate, newYear);
}

public boolean isRentalOverdue(DateTime datetimeRented) {
  Period rentalPeriod = new Period().withDays(2).withHours(12);
  return datetimeRented.plus(rentalPeriod).isBeforeNow();
}

public String getBirthMonthText(LocalDate dateOfBirth) {
  return dateOfBirth.monthOfYear().getAsText(Locale.ENGLISH);
}

Questa è esteso Versino di Balus di c implementazione.

Prova questo, ho implementato utilizzando Joda-datatime2.2.jar e SimpleDateFormat

import java.text.SimpleDateFormat;
import java.util.Date;
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.Days;
public class SmartDateTimeUtil {
private static String getHourMinuteString(Date date){
    SimpleDateFormat hourMinuteFormat = new SimpleDateFormat(" h:m a");
    return hourMinuteFormat.format(date);
}

private static String getDateString(Date date){
    SimpleDateFormat dateStringFormat = new SimpleDateFormat("EEE',' MMM d y',' h:m a");
    return dateStringFormat.format(date);
}

private static boolean isToday (DateTime dateTime) {
       DateMidnight today = new DateMidnight();
       return today.equals(dateTime.toDateMidnight());
}

private static boolean isYesterday (DateTime dateTime) {
       DateMidnight yesterday = (new DateMidnight()).minusDays(1);
       return yesterday.equals(dateTime.toDateMidnight());
}

private static boolean isTomorrow(DateTime dateTime){
    DateMidnight tomorrow = (new DateMidnight()).plusDays(1);
       return tomorrow.equals(dateTime.toDateMidnight());
}
private static String getDayString(Date date) {
        SimpleDateFormat weekdayFormat = new SimpleDateFormat("EEE',' h:m a");
        String s;
        if (isToday(new DateTime(date)))
            s = "Today";
        else if (isYesterday(new DateTime(date)))
            s = "Yesterday," + getHourMinuteString(date);
        else if(isTomorrow(new DateTime(date)))
            s = "Tomorrow," +getHourMinuteString(date);
        else
            s = weekdayFormat.format(date);
        return s;
}

public static String getDateString_shortAndSmart(Date date) {
        String s;
        DateTime nowDT = new DateTime();
        DateTime dateDT = new DateTime(date);
        int days = Days.daysBetween(dateDT, nowDT).getDays();   
        if (isToday(new DateTime(date)))
            s = "Today,"+getHourMinuteString(date);
        else if (days < 7)
            s = getDayString(date);
        else
            s = getDateString(date);
        return s;
}

}

Casi semplici da usare e testare la classe Util:

import java.util.Calendar;
import java.util.Date;

public class SmartDateTimeUtilTest {
    public static void main(String[] args) {
        System.out.println("Date now:"+SmartDateTimeUtil.getDateString_shortAndSmart(new Date()));
        System.out.println("Date 5 days before :"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureDay(-5)));
        System.out.println("Date 1 day before :"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureDay(-1)));
        System.out.println("Date last month:"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureMonth(-1)));
        System.out.println("Date last year:"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureDate(-1)));
        System.out.println("Date 1 day after :"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureDay(1)));
    }
    public static Date getFutureDate(int numberOfYears){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.YEAR, numberOfYears); 
        return c.getTime();
    }
    public static Date getFutureMonth(int numberOfYears){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.MONTH, numberOfYears); 
        return c.getTime();
    }

    public static Date getFutureDay(int numberOfYears){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, numberOfYears); 
        return c.getTime();
    }
}

Lo so che sono in ritardo a questo partito. Ma ho la soluzione più breve per questo problema. Se si desidera mostrare "Oggi" o "Yesterday" sulla base del Data , allora non vi resta che utilizzare questo

String strDate = "";
if (DateUtils.isToday(date.getTime()))
    strDate = "Today";
else if (DateUtils.isToday(date.getTime() + DateUtils.DAY_IN_MILLIS))
    strDate = "Yesterday";

data qui variabile è il href="https://developer.android.com/reference/java/util/Date.html" rel="nofollow noreferrer"> oggetto Date

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top