Java.util.Date to java.time.LocalDate এ রূপান্তর করুন


494

java.util.Dateনতুন জেডিকে 8 / জেএসআর -310 এ কোনও বস্তুকে রূপান্তর করার সর্বোত্তম উপায় কী java.time.LocalDate?

Date input = new Date();
LocalDate date = ???

উত্তর:


828

সংক্ষিপ্ত উত্তর

Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

ব্যাখ্যা

এর নাম সত্ত্বেও, java.util.Dateসময়রেখায় একটি তাত্ক্ষণিক প্রতিনিধিত্ব করে, "তারিখ" নয়। বস্তুর মধ্যে সংরক্ষিত প্রকৃত তথ্য হ'ল long1970-01-01T00: 00Z (1970 জিএমটি / ইউটিসি শুরুতে মধ্যরাত) সাল থেকে মিলিসেকেন্ডের একটি গণনা।

java.util.Dateজেএসআর -310 এর সমতুল্য শ্রেণি Instant, সুতরাং toInstant()রূপান্তর সরবরাহের জন্য একটি সুবিধাজনক পদ্ধতি রয়েছে :

Date input = new Date();
Instant instant = input.toInstant();

একটি java.util.Dateউদাহরণ হিসেবে বলা যায় সময় অঞ্চল কোন ধারণা আছে। আপনি যদি কল toString()করেন তবে এটি অদ্ভুত বলে মনে হতে পারে java.util.Dateকারণ toStringসময় অঞ্চলটির সাথে সম্পর্কিত the তবে সেই পদ্ধতিটি স্ট্রিং সরবরাহ করতে ফ্লাইতে জাওয়ার ডিফল্ট সময় অঞ্চলটি ব্যবহার করে। সময় অঞ্চলটি আসল অবস্থার অংশ নয় java.util.Date

একটিতে Instantসময়-অঞ্চল সম্পর্কে কোনও তথ্য থাকে না। সুতরাং, একটি Instantথেকে স্থানীয় তারিখে রূপান্তর করার জন্য একটি সময়-অঞ্চল নির্দিষ্ট করা প্রয়োজন। এটি ডিফল্ট অঞ্চল হতে পারে - ZoneId.systemDefault()- বা এটি এমন একটি সময়-অঞ্চল হতে পারে যা আপনার অ্যাপ্লিকেশন নিয়ন্ত্রণ করে, যেমন ব্যবহারকারীর পছন্দসমূহ থেকে সময়-অঞ্চল। atZone()সময়-অঞ্চল প্রয়োগ করতে পদ্ধতিটি ব্যবহার করুন :

Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());

ZonedDateTimeএটিতে স্থানীয় তারিখ এবং সময়, সময় অঞ্চল এবং জিএমটি / ইউটিসি থেকে অফসেট সমন্বিত একটি রাষ্ট্র রয়েছে। যেমন তারিখ - LocalDate- সহজেই ব্যবহার করে উত্তোলন করা যেতে পারে toLocalDate():

Date input = new Date();
Instant instant = input.toInstant();
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
LocalDate date = zdt.toLocalDate();

জাভা 9 উত্তর

জাভা এসই 9 এ, একটি নতুন পদ্ধতি যুক্ত করা হয়েছে যা এই কাজটিকে সামান্য সরল করে:

Date input = new Date();
LocalDate date = LocalDate.ofInstant(input.toInstant(), ZoneId.systemDefault());

এই নতুন বিকল্পটি আরও সরাসরি, কম আবর্জনা তৈরি করে এবং এর ফলে আরও ভাল সম্পাদন করা উচিত।


14
আমার LocalDate.from(Instant.ofEpochMilli(date.getTime()))মনে হয়েছিল এটি আপনার সমতুল্য, তবে আরও সরাসরি।
মার্কো টপলনিক

9
@ মার্কো টপলনিক যা সংকলন করে তবে চালিত হয় না। একটি তাত্ক্ষণিকের সময়-অঞ্চল থাকে না সুতরাং লোকাল ডেট পাওয়ার কোনও উপায় নেই।
জোদাস্টেফেন

11
@Alilias just sqlDate.toLocalDate () ব্যবহার করুন!
জোদাস্টেফেন

25
@ জোডাস্টেফেনের Dateসময়-অঞ্চল সম্পর্কে কোনও ধারণা নেই, Instantএছাড়াও সময়-অঞ্চল সম্পর্কিত তথ্য নেই। LocalDateএপিআই বলছেন "একসাথে একটি-জোন ছাড়া একটি তারিখ"। তাহলে কেন থেকে রূপান্তর Dateকরতে Instantকরতে LocalDateচাহিদা atZone(ZoneId.systemDefault())?
গুস্তাভো

8
@ গুস্তাভো: LocalDateএবং LocalDateTime"কোনও সময় বা সময় অঞ্চলকে সংরক্ষণ বা প্রতিনিধিত্ব করবেন না" (রেফার: জাভাদোকস)। যদিও তারা এটি সংরক্ষণ করে না - ক্লাসগুলি একটি Localতারিখ এবং / অথবা সময় উপস্থাপন করে, তাই স্থানীয় তারিখ / সময় রূপান্তর একটি সময় অঞ্চলকে বোঝায়।
কুগা

158

আরও ভাল উপায়:

Date date = ...;
Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate()

এই সংস্করণটির সুবিধা:

  • ইনপুটটি উদাহরণস্বরূপ java.util.Dateবা এটি একটি সাবক্লাস java.sql.Date(@ জোদাস্টেফেনের মতো নয়) এর কাজ করে regard এটি জেডিবিসি-উত্পন্ন ডেটার সাথে সাধারণ। java.sql.Date.toInstant()সর্বদা একটি ব্যতিক্রম নিক্ষেপ।

  • এটি JDK8 এবং JDK7 জেএসআর -310 ব্যাকপোর্ট সহ একই

আমি ব্যক্তিগতভাবে একটি ইউটিলিটি ক্লাস ব্যবহার করি (তবে এটি ব্যাকপোর্টের সাথে সামঞ্জস্যপূর্ণ নয়):

/**
 * Utilities for conversion between the old and new JDK date types 
 * (between {@code java.util.Date} and {@code java.time.*}).
 * 
 * <p>
 * All methods are null-safe.
 */
public class DateConvertUtils {

    /**
     * Calls {@link #asLocalDate(Date, ZoneId)} with the system default time zone.
     */
    public static LocalDate asLocalDate(java.util.Date date) {
        return asLocalDate(date, ZoneId.systemDefault());
    }

    /**
     * Creates {@link LocalDate} from {@code java.util.Date} or it's subclasses. Null-safe.
     */
    public static LocalDate asLocalDate(java.util.Date date, ZoneId zone) {
        if (date == null)
            return null;

        if (date instanceof java.sql.Date)
            return ((java.sql.Date) date).toLocalDate();
        else
            return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDate();
    }

    /**
     * Calls {@link #asLocalDateTime(Date, ZoneId)} with the system default time zone.
     */
    public static LocalDateTime asLocalDateTime(java.util.Date date) {
        return asLocalDateTime(date, ZoneId.systemDefault());
    }

    /**
     * Creates {@link LocalDateTime} from {@code java.util.Date} or it's subclasses. Null-safe.
     */
    public static LocalDateTime asLocalDateTime(java.util.Date date, ZoneId zone) {
        if (date == null)
            return null;

        if (date instanceof java.sql.Timestamp)
            return ((java.sql.Timestamp) date).toLocalDateTime();
        else
            return Instant.ofEpochMilli(date.getTime()).atZone(zone).toLocalDateTime();
    }

    /**
     * Calls {@link #asUtilDate(Object, ZoneId)} with the system default time zone.
     */
    public static java.util.Date asUtilDate(Object date) {
        return asUtilDate(date, ZoneId.systemDefault());
    }

    /**
     * Creates a {@link java.util.Date} from various date objects. Is null-safe. Currently supports:<ul>
     * <li>{@link java.util.Date}
     * <li>{@link java.sql.Date}
     * <li>{@link java.sql.Timestamp}
     * <li>{@link java.time.LocalDate}
     * <li>{@link java.time.LocalDateTime}
     * <li>{@link java.time.ZonedDateTime}
     * <li>{@link java.time.Instant}
     * </ul>
     * 
     * @param zone Time zone, used only if the input object is LocalDate or LocalDateTime.
     * 
     * @return {@link java.util.Date} (exactly this class, not a subclass, such as java.sql.Date)
     */
    public static java.util.Date asUtilDate(Object date, ZoneId zone) {
        if (date == null)
            return null;

        if (date instanceof java.sql.Date || date instanceof java.sql.Timestamp)
            return new java.util.Date(((java.util.Date) date).getTime());
        if (date instanceof java.util.Date)
            return (java.util.Date) date;
        if (date instanceof LocalDate)
            return java.util.Date.from(((LocalDate) date).atStartOfDay(zone).toInstant());
        if (date instanceof LocalDateTime)
            return java.util.Date.from(((LocalDateTime) date).atZone(zone).toInstant());
        if (date instanceof ZonedDateTime)
            return java.util.Date.from(((ZonedDateTime) date).toInstant());
        if (date instanceof Instant)
            return java.util.Date.from((Instant) date);

        throw new UnsupportedOperationException("Don't know hot to convert " + date.getClass().getName() + " to java.util.Date");
    }

    /**
     * Creates an {@link Instant} from {@code java.util.Date} or it's subclasses. Null-safe.
     */
    public static Instant asInstant(Date date) {
        if (date == null)
            return null;
        else
            return Instant.ofEpochMilli(date.getTime());
    }

    /**
     * Calls {@link #asZonedDateTime(Date, ZoneId)} with the system default time zone.
     */
    public static ZonedDateTime asZonedDateTime(Date date) {
        return asZonedDateTime(date, ZoneId.systemDefault());
    }

    /**
     * Creates {@link ZonedDateTime} from {@code java.util.Date} or it's subclasses. Null-safe.
     */
    public static ZonedDateTime asZonedDateTime(Date date, ZoneId zone) {
        if (date == null)
            return null;
        else
            return asInstant(date).atZone(zone);
    }

}

এখানে asLocalDate()পদ্ধতিটি নাল-নিরাপদ, ব্যবহার রয়েছে toLocalDate(), যদি ইনপুট হয় java.sql.Date(টাইমজোন সমস্যা বা অপ্রয়োজনীয় গণনা এড়াতে এটি জেডিবিসি ড্রাইভারের দ্বারা চালিত হতে পারে), অন্যথায় উপরোক্ত পদ্ধতিটি ব্যবহার করে।


12
যদি এটি আরও ভাল উপায় হয় তবে এটি খুব কুরুচিপূর্ণ এবং ভার্বোস। তাই বেদনাদায়ক.
সেকলক

3
এটি গৃহীত উত্তরের তুলনায় ভাল, কেন আমি তা ব্যাখ্যা করি। হ্যাঁ, এটি কুরুচিপূর্ণ, তবে সে কারণেই লিখেছেন DateConvertUtils
অলিভ

তারা কেন নতুন এপিআইতে রূপান্তর শ্রেণি প্রয়োগ করেনি তা আমি বুঝতে পারি না।
সেকলক

@ceklock, তারা হয়নি বাস্তবায়ন, না একটি রূপান্তর বর্গ, কিন্তু রূপান্তর পদ্ধতি দম্পতি, মত Date.toInstant()
ওলে ভিভি

2
এমন কোনও কোটলিন লাইব্রেরি রয়েছে যা এগুলিকে এক্সটেনশন ফাংশন হিসাবে প্যাকেজ করে যাতে কোনও বিকাশকারী নিম্নলিখিতটি করতে পারে। তারিখ x = ...; x.asLocalDate ();
মার্ক অশ্বওয়ার্থ

20
LocalDate localDate = LocalDate.parse( new SimpleDateFormat("yyyy-MM-dd").format(date) );

7
এখানে, SimpleDateFormatউদাহরণটি বর্তমান থ্রেডের মধ্যে সীমাবদ্ধ । এটি থ্রেড-নিরাপদ উপায়ে ব্যবহৃত হয়। এখন, SimpleDateFormatএটি 'ইনস্ট্যান্টিয়েট করা ব্যয়বহুল' হিসাবে স্বীকৃত (এটি প্রয়োজনীয় সমস্ত অভ্যন্তরীণ ডেটা স্ট্রাকচারের কারণে) তবে আপনি 'সিঙ্গলটন' হিসাবে এটি ভাগ করতে পারবেন না (এটি অ্যাক্সেসের সাথে সিঙ্ক্রোনাইজ না করে), কারণ এটি থ্রেড- নিরাপদ। ( কোডটি 'দূষিত' করে যদি একটি ThreadLocalসমাধান কাজ করতে পারেThread তবে থ্রেডের জীবনচক্রের জন্য দায়বদ্ধ ... তবে এটি খুব কমই ঘটে)। বিশ্রী। এড়ানো SimpleDateFormatহয় ব্যবহার করার জন্য কারণ । javax.time
ডেভিড বুলক

6
এই পদ্ধতির প্রচুর ওভারহেড রয়েছে: 'ব্যয়বহুল' SimpleDateFormat(যা ফেলে দেওয়া হয়), মধ্যবর্তী স্ট্রিং (যা ফেলে দেওয়া হয়) এবং পার্সিংয়ের ব্যয়। এটি একটি সমাধান, তবে প্রস্তাবিত নয়।
ডেভিড বুলক

2
@ এস্কলক তবে আপনি সমস্যাটি পেয়ে যাবেন যে এটি আর থ্রেড-নিরাপদ নেই
ফ্লপ করুন

4
সিম্পলকডেটফরম্যাটটি কেবলমাত্র একবারে একটি তারিখ প্রক্রিয়া করতে পারে, আপনি যদি এটি একই সাথে ব্যবহার করেন তবে তা মঙ্গলের ফলাফল পাবে। হ্যাঁ, এটা গুরুত্বপূর্ণ। গ্লোবাল ভেরিয়েবলে সিম্পলডেট ফরমেটের একক উদাহরণ তৈরি করবেন না।
ফ্লপ

19

আপনি যদি জাভা 8 ব্যবহার করেন তবে @ জোডাস্টেফেনের উত্তরটি অবশ্যই সবচেয়ে ভাল। তবে, আপনি যদি জেএসআর -310 ব্যাকপোর্টের সাথে কাজ করছেন তবে দুর্ভাগ্যক্রমে আপনাকে এরকম কিছু করতে হবে:

Date input = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(input);
LocalDate date = LocalDate.of(cal.get(Calendar.YEAR),
        cal.get(Calendar.MONTH) + 1,
        cal.get(Calendar.DAY_OF_MONTH));

4
সত্য নয়, @ জোডাস্টেফেনের উত্তর এখনও কার্যকর হয়। Java.util. তারিখটিকে তাত্ক্ষণিকভাবে রূপান্তর করার জন্য আপনার আর একটি উপায় প্রয়োজন। এর জন্য আপনি org.threeten.bp.DateTimeUtils.toInstant ব্যবহার করতে পারেন: threeten.org/threetenbp/apidocs/org/threeten/bp/…
খ্রিস্টান সিচ

3
আমি যখন ব্যাকপোর্টটি ব্যবহার করছিলাম তখন ডেটটাইম ইউটিলগুলি উপলভ্য ছিল না তবে আপনি সঠিক যে এটি থ্রিটেন ব্যাকপোর্ট ০.০ বা তার পরে ব্যবহার করে যে কারও কাছে পাওয়া যায়। এটা ইশারা জন্য ধন্যবাদ।
haালসিম 2


8

আপনি এক লাইনে রূপান্তর করতে পারেন:

public static LocalDate getLocalDateFromDate(Date date){
   return LocalDate.from(Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()));
}

আমি এই পদ্ধতিটি ব্যবহার করে এর মতো ত্রুটি পেয়েছি: জাভা.টাইম.ডেটটাইম এক্সেপশন: টেম্পোরাল অ্যাকসেসর থেকে 2018-01-31T11: 54: 27.964Z টাইপ জাভা.টাইম.ইনস্ট্যান্ট
লুইজি রুবিনো

@ LuigiRubino নির্দেশ করার জন্য ধন্যবাদ। আপডেট উত্তর দেখুন। আমি আগে জোন যুক্ত করতে ভুলে গেছি।
সাহিল ছাবার

8

প্রথমত, তারিখটিকে তাত্ক্ষণিকভাবে রূপান্তর করা সহজ

Instant timestamp = new Date().toInstant(); 

তারপরে, আপনি ইনস্ট্যান্ট () পদ্ধতি ব্যবহার করে jdk 8-এ তাত্ক্ষণিক যে কোনও তারিখ এপিতে রূপান্তর করতে পারেন:

LocalDateTime date = LocalDateTime.ofInstant(timestamp, ZoneId.systemDefault()); 

লোকালডেট, লোকালডেটটাইম, লোকালটাইম
শেডম ওয়ে

এখানে জোনআইড নির্দিষ্ট করার অর্থ কী। যদি আমি এপিআই থেকে তারিখ -> তাত্ক্ষণিকতা পাই এবং আমি এটি ইউটিসিতে 1970 থেকে মিলিসেকেন্ড হিসাবে ভাবতে পারি। আমি যখন এপিআইকে কোনও টাইমজোনতে রূপান্তরিত করব না এমন দৃষ্টিকোণ থেকে কেবল স্থানীয় স্থানীয় তারিখ (yyyy-মিমি-ডিডি) পেতে চাই, আমি আমার স্থানীয় টাইমজোনটিতে তাত্ক্ষণিক অফসেট না পাওয়ার জন্য জোনঅফসেট.আউটসি ব্যবহার করা উচিত নয়। জোনআইড.সিস্টেমডিফাল্ট () এর সাথে আপনার উদাহরণটি কি তারিখের ফর্ম সার্ভারটি স্থানান্তর করছে। যাত্রা। তাত্ক্ষণিকভাবে 2018-10-20 0:00 টি উপস্থাপন করে এবং তারপরে ইউটিসি থেকে আমেরিকা / লস_এঞ্জেলসে স্থানান্তরিত হয়ে আমি স্থানীয় তারিখ 2018-10-19 এ পাব 2018-10-20?
মিশা জিওব্রো

import java.sql.Dateআপনার ফাইলটিতে থাকলে তা ভেঙে যায় : সর্বদা নিক্ষেপ করার toInstant()পদ্ধতি java.sql.Date
অলিভ

4
Date input = new Date();
LocalDateTime  conv=LocalDateTime.ofInstant(input.toInstant(), ZoneId.systemDefault());
LocalDate convDate=conv.toLocalDate();

Dateউদাহরণ হিসেবে বলা যায় তারিখ খুব বরাবর সময় ধারণ করার সময় নেই LocalDateনা। সুতরাং আপনি প্রথমে LocalDateTimeএর পদ্ধতিটি ব্যবহার করে রূপান্তর করতে পারেন ofInstant()তারপর যদি আপনি সময় ব্যতীত চান তবে উদাহরণটি রূপান্তর করুন LocalDate


1
public static LocalDate Date2LocalDate(Date date) {
        return LocalDate.parse(date.toString(), DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy"))

এই ফর্ম্যাট থেকে Date#tostring

    public String toString() {
        // "EEE MMM dd HH:mm:ss zzz yyyy";
        BaseCalendar.Date date = normalize();
        StringBuilder sb = new StringBuilder(28);
        int index = date.getDayOfWeek();
        if (index == BaseCalendar.SUNDAY) {
            index = 8;
        }
        convertToAbbr(sb, wtb[index]).append(' ');                        // EEE
        convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
        CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd

        CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
        CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
        CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
        TimeZone zi = date.getZone();
        if (zi != null) {
            sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
        } else {
            sb.append("GMT");
        }
        sb.append(' ').append(date.getYear());  // yyyy
        return sb.toString();
    }

0

আমি @ JBoss ইএপি 6. সুতরাং JodaStephen বাস্তবায়ন, আমি ওরাকল এর জাভা টিউটোরিয়াল নিম্নলিখিত রূপান্তর rewrote সমস্যা ছিল http://docs.oracle.com/javase/tutorial/datetime/iso/legacy.html

    Date input = new Date();
    GregorianCalendar gregorianCalendar = (GregorianCalendar) Calendar.getInstance();
    gregorianCalendar.setTime(input);
    ZonedDateTime zonedDateTime = gregorianCalendar.toZonedDateTime();
    zonedDateTime.toLocalDate();

-2

এই 1 টি সাধারণ লাইনে কী ভুল?

new LocalDateTime(new Date().getTime()).toLocalDate();

জাভা অভিযোগ করে যে এটি দীর্ঘকালীন প্রকারভেদে লোকালডেট () এ আবেদন করতে পারে না। আমি একটি আসল তারিখ অবজেক্ট ব্যবহার করেছি; সম্ভবত ঘষা আছে ??
TheGeeko61

-8

আমি নীচে সমাধান দিয়ে এই প্রশ্নটি সমাধান করেছি

  import org.joda.time.LocalDate;
  Date myDate = new Date();
  LocalDate localDate = LocalDate.fromDateFields(myDate);
  System.out.println("My date using Date" Nov 18 11:23:33 BRST 2016);
  System.out.println("My date using joda.time LocalTime" 2016-11-18);

এক্ষেত্রে স্থানীয় তারিখ এই তারিখটি "yyyy-MM-dd" বিন্যাসে মুদ্রণ করুন


1
প্রশ্নটি java.timeJDK8 এর ক্লাসগুলি ব্যবহার করে কোনও সমাধানের সন্ধান করছে, জোদা টাইমের সাথে নয়।
পাইওটো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.