Java 比较字符串类型的日期

Java 比较字符串类型的日期,java,string,date,comparable,compareto,Java,String,Date,Comparable,Compareto,我有一个任务对象,它有一个名称和一个日期。日期值必须是字符串。例如,将11/9/2015 23:00与11/24/2015 12:00进行比较。 我需要帮助为此编写一个compareTo(),以便首先显示最快日期的任务。我所拥有的是不正确的,因为它不能正确比较。我知道有其他选择,但这是我必须这样做的字符串。我曾考虑过使用.split()将mm/dd/yyyyy分解为“/”,但不确定如何执行此操作 public class Task implements Comparable<Task>

我有一个任务对象,它有一个名称和一个日期。日期值必须是
字符串
。例如,将
11/9/2015 23:00
11/24/2015 12:00
进行比较。 我需要帮助为此编写一个
compareTo()
,以便首先显示最快日期的任务。我所拥有的是不正确的,因为它不能正确比较。我知道有其他选择,但这是我必须这样做的字符串。我曾考虑过使用
.split()
将mm/dd/yyyyy分解为
“/”
,但不确定如何执行此操作

public class Task implements Comparable<Task> {
    /** Task name. */
    private String name;
    /** Task due date. */
    private String dueDate;

    /**
     * Initializes a tasks name and due date.
     * @param n Name
     * @param d due date
     */
    public Task(String n, String d) {
        name = n;
        dueDate = d;
    }

    /**
     * Accessor for task name.
     * @return Task name.
     */
    public String getName() {
        return name;
    }

    /**
     * Accessor for task due date.
     * @return Task due date.
     */
    public String getDueDate() {
        return dueDate;
    }

    /**
     * Compares the due dates of the tasks to get the soonest to the front of the list.
     * @param t The task to compare.
     * @return The tasks in chronological order.
     */
    @Override
    public int compareTo(Task t) { //Need help here.
        int val = dueDate.compareTo(t.getDueDate());

        if(val == 0) {
            val = name.compareTo(t.getName());
        }
        if(dueDate.compareTo(t.getDueDate()) > 0) {
            val = -1;
        }
        if(dueDate.compareTo(t.getDueDate()) < 0) {
            val = 1;
        }   
        return val;
    }
公共类任务实现可比较{
/**任务名称*/
私有字符串名称;
/**任务到期日*/
私有字符串到期日;
/**
*初始化任务名称和到期日期。
*@param n Name
*@param d到期日
*/
公共任务(字符串n,字符串d){
name=n;
dueDate=d;
}
/**
*任务名称的访问器。
*@return任务名。
*/
公共字符串getName(){
返回名称;
}
/**
*任务到期日的访问者。
*@返回任务截止日期。
*/
公共字符串getDueDate(){
归还日期;
}
/**
*比较任务的截止日期,以便最快地到达列表的前面。
*@param t指定要比较的任务。
*@按时间顺序返回任务。
*/
@凌驾
public int compareTo(Task t){//此处需要帮助。
int val=dueDate.compareTo(t.getDueDate());
如果(val==0){
val=name.compareTo(t.getName());
}
if(dueDate.compareTo(t.getDueDate())>0){
val=-1;
}
if(dueDate.compareTo(t.getDueDate())<0){
val=1;
}   
返回val;
}

必须将日期作为字符串,这并不意味着不能将其转换为日期,并使用该类的自然顺序:

@Override
public int compareTo(Task t) {
    // Handling ParseExceptions omitted for bravity's sake
    SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm");
    Date d1 = df.parse(dueDate);
    Date d2 = df.parse(t.getDueDate());

    int val = d1.compareTo(d2);

    if(val != 0) {
        return val;    
    }
    return name.compareTo(t.getName());
}
日期时间对象 我建议您在类中使用日期时间对象而不是字符串作为成员

Java8和更高版本包含了非常有用的框架。使用这些新类(受其启发)而不是臭名昭著的麻烦的旧类Java.util.Date/.Calendar

无需解析日期-时间输入字符串。默认情况下,java.time框架解析格式中的任何字符串。对于其他格式,请定义预期输入的格式化程序模式,并让java.time完成此工作

时区 您无法在不知道其时区的情况下比较您的日期时间字符串。可能是这样?或者您是否假设所有数据都指向特定的时区

在下面的示例中,我任意假设时区为

示例代码。 Java 8中的示例代码使用包解析字符串以在构造函数中输入,并再次在
dueDateTimeAsAmericaLosAngeles
方法中生成字符串表示

通常,最好将日期时间值保持在UTC时区。然后在用户或其他软件期望时调整到时区。因此,我们在类上存储一个
即时
,在UTC时间轴上存储一个时刻。对于特定时区,创建一个
ZonedDateTime
对象

如果违背我的建议,您坚持将日期时间值存储为字符串,那么您可以通过移动字符串解析的位置来修改此代码

package timestuff;

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Task implements Comparable<Task> {

    String title;
    Instant due;

    public Task ( String title , String dateTimeAssumedToBeAmericaLosAngles ) {
        this.title = title;
        ZoneId zoneId = ZoneId.of ( "America/Los_Angeles" );
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "M/d/yyyy HH:mm" ).withZone ( zoneId ); // Example data: 11/24/2015 12:00
        this.due = formatter.parse ( dateTimeAssumedToBeAmericaLosAngles , Instant :: from );
    }

    @Override
    public String toString () {
        return "Task{ " + "title=" + title + " | instant=" + due + " }";
    }

    @Override
    public int compareTo ( Task t ) {
        // Sort by the date-time of when this task is due.
        int result = this.due.compareTo ( t.due );
        return result;
    }

    String dueDateTimeAsAmericaLosAngeles () {
        ZoneId zoneId = ZoneId.of ( "America/Los_Angeles" );
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "M/d/yyyy HH:mm" ).withZone ( zoneId ); // Example data: 11/24/2015 12:00
        ZonedDateTime zdt = ZonedDateTime.ofInstant ( this.due , zoneId );
        String output = zdt.format ( formatter );
        return output;
    }

    public static void main ( String[] args ) {
        Task t1 = new Task ( "x" , "11/9/2015 23:00" );
        Task t2 = new Task ( "y" , "11/24/2015 12:00" );
        int compared = t1.compareTo ( t2 );
        System.out.println ( "t1: " + t1 + " & t2: " + t2 + " compared: " + compared );
    }

}
package timestaff;
导入java.time.Instant;
导入java.time.ZoneId;
导入java.time.ZonedDateTime;
导入java.time.format.DateTimeFormatter;
公共类任务实现了可比性{
字符串标题;
即时到期;
公共任务(字符串标题、字符串DateTimeAssumedTobeAmericalAngles){
this.title=标题;
ZoneId ZoneId=ZoneId.of(“美国/洛杉矶”);
DateTimeFormatter formatter=DateTimeFormatter.of模式(“M/d/yyyy HH:mm”).withZone(zoneId);//示例数据:11/24/2015 12:00
this.due=formatter.parse(DateTimeAssumedTobeAmericalAngles,Instant::from);
}
@凌驾
公共字符串toString(){
返回“Task{“+”title=“+title+”| instant=“+due+”}”;
}
@凌驾
公共整数比较(任务t){
//按此任务到期的日期和时间排序。
int结果=this.due.compareTo(t.due);
返回结果;
}
字符串dueDateTimeAsAmericaLosAngeles(){
ZoneId ZoneId=ZoneId.of(“美国/洛杉矶”);
DateTimeFormatter formatter=DateTimeFormatter.of模式(“M/d/yyyy HH:mm”).withZone(zoneId);//示例数据:11/24/2015 12:00
ZonedDateTime zdt=ZonedDateTime.ofInstant(this.due,zoneId);
字符串输出=zdt.format(格式化程序);
返回输出;
}
公共静态void main(字符串[]args){
任务t1=新任务(“x”,“11/9/2015 23:00”);
任务t2=新任务(“y”,“11/24/2015 12:00”);
int比较=t1.compareTo(t2);
System.out.println(“t1:+t1+”和t2:+t2+”比较:“+compared”);
}
}
运行时:

t1:任务{title=x | instant=2015-11-10T07:00:00Z}&t2:任务{title=y | instant=2015-11-24T20:00:00Z}比较:-1


你能转换成日期对象然后进行比较吗?@AbtPst No的可能重复项我必须使用
String
@AlexShesterov不完全重复,因为这个问题是关于日期-时间的,而你的链接只是关于日期。这里有另一个近似重复项,但只有日期:。你能解释为什么你必须使用字符串而不是日期吗?