জাভা মধ্যে একটি সময়কাল বিন্যাস কিভাবে? (যেমন ফর্ম্যাট এইচ: এমএম: এসএস)


164

আমি এইচ: এমএম: এসএস এর মতো প্যাটার্ন ব্যবহার করে কয়েক সেকেন্ডের মধ্যে একটি সময়কাল বিন্যাস করতে চাই। জাভাতে বিদ্যমান ইউটিলিটিগুলি কোনও সময় বিন্যাসের জন্য নয় কিন্তু সময় বিন্যাস করার জন্য ডিজাইন করা হয়েছে।

উত্তর:


84

আপনি যদি 8 এর আগে জাভাটির কোনও সংস্করণ ব্যবহার করেন তবে আপনি জোদা সময় এবং ব্যবহার করতে পারেন PeriodFormatter। যদি আপনি সত্যিই একটি সময়কাল পেয়ে থাকেন (যেমন একটি ক্যালেন্ডার সিস্টেমের সাথে উল্লেখ না করে সময় অতিবাহিত পরিমাণ) তবে সম্ভবত Durationআপনার বেশিরভাগ অংশ ব্যবহার করা উচিত - আপনি তখন কল করতে পারেন toPeriod( PeriodType25 ঘন্টা হয়ে যায় কিনা তা প্রতিফলিত করতে চান তা নির্দিষ্ট করে) Periodআপনি ফর্ম্যাট করতে পারেন এমন একটি পেতে 1 দিন এবং 1 ঘন্টা বা না, ইত্যাদি) ।

আপনি যদি জাভা 8 বা তার পরে ব্যবহার করছেন: আমি সাধারণত java.time.Durationসময়কালটি উপস্থাপন করার জন্য ব্যবহার করার পরামর্শ দিই । তারপরে আপনি getSeconds()যদি প্রয়োজন হয় তবে বোবিন্সের উত্তর অনুসারে স্ট্যান্ডার্ড স্ট্রিং ফর্ম্যাটিংয়ের জন্য একটি পূর্ণসংখ্যা পেতে কল করতে বা পছন্দ করতে পারেন - যদিও আপনাকে সময়কালটি নেতিবাচক এমন পরিস্থিতিতে সতর্ক হওয়া উচিত, কারণ আপনি সম্ভবত আউটপুট স্ট্রিংয়ে একটি একক নেতিবাচক চিহ্ন চান । সুতরাং যেমন কিছু:

public static String formatDuration(Duration duration) {
    long seconds = duration.getSeconds();
    long absSeconds = Math.abs(seconds);
    String positive = String.format(
        "%d:%02d:%02d",
        absSeconds / 3600,
        (absSeconds % 3600) / 60,
        absSeconds % 60);
    return seconds < 0 ? "-" + positive : positive;
}

বিরক্তিকরভাবে ম্যানুয়াল থাকলে এইভাবে ফর্ম্যাট করা যুক্তিসঙ্গতভাবে সহজ। জন্য পার্স এটি একটি কঠিন ব্যাপার সাধারণভাবে হয়ে ... আপনি এখনও এমনকি জাভা 8 Joda সময় ব্যবহার করেন আপনি অবশ্যই, করতে চান পারে।


আপনি কি জাভা 8 ব্যবহার করার সময় জোদা টাইম লাইব্রেরিটি ব্যবহার করার পরামর্শ দিবেন?
টিম বাথ

1
@ টিমবাথ: না, আমি সেই ক্ষেত্রে জাভা.টাইম ব্যবহার শুরু করব। (যদিও আমি অবিলম্বে পিরিয়ডফর্ম্যাটারের সমতুল্য খুঁজে পাচ্ছি না ...)
জন স্কিটি

1
পিরিয়ড ফরমেটারটি অন্তর্ভুক্ত নেই। জাভা 8 তারিখের সময় API এবং জোদা সময়ের মধ্যে পার্থক্যগুলির মধ্যে এটি।
টিম বাথ

1
@ রেক্সেরার: ঠিক আছে, অবশ্যই যদি আপনি চান অবশ্যই "জোদা সময়" ব্যবহার করুন। আবার সম্পাদনা করবে। (পিছনে ফিরে তাকানোর পরে, এর আওয়াজ অনুসারে আমার অবশ্যই সময়কাল সুপারিশ করা উচিত ছিল Sign তাৎপর্যপূর্ণ সম্পাদনা প্রয়োজন ...)
জন স্কিটে

4
@MarkJeronimus এমনকি সহজ ব্যবহার করতে হবে Durationগুলি পদ্ধতি: duration.toHours(), duration.toMinutesPart()এবং duration.toSecondsPart()যা জাভা 9. যেহেতু উপলব্ধ এবং পেতে পরম মান ব্যবহার করতে পারেন duration.abs()
recke96

195

আপনি যদি লাইব্রেরিতে টেনে আনতে না চান তবে একটি ফর্ম্যাটর, বা সম্পর্কিত শর্টকাট যেমন using সেকেন্ডের সংখ্যার পূর্ণসংখ্যার সংখ্যা:

  String.format("%d:%02d:%02d", s / 3600, (s % 3600) / 60, (s % 60));

4
পূর্ণসংখ্যা হতে হবে না। আপনার যদি দুটি তারিখ থাকে তবে উপরের সমীকরণটিতে কেবল তারিখ 1.টিজটাইম () - ডেট 2.সেটটাইম () প্লাগ করুন যা দীর্ঘ আদিম ব্যবহার করে এবং এখনও কাজ করে।
জোশ

সময়ের পার্থক্য যদি 24 ঘন্টা অপেক্ষা দীর্ঘ হয় তবে কী হবে?
রাজিশ

2
@ রাজীশ: আপনাকে ওপি জিজ্ঞাসা করতে হবে যে তারা এই ক্ষেত্রে কী চায়! অবশ্যই আপনি s/86400, (s%86400)/3600...প্রয়োজনে কয়েক দিনের জন্য এটি আলাদা করতে পারেন ...
ববিনস

s > 86400 (একদিন) -এর আমার সমাধান : "\u221E"- অনন্ততা
QED

যদি সময়ের পার্থক্য 24 ঘন্টাের বেশি হয় তবে এটি ঘন্টা, মিনিট এবং সেকেন্ডের মধ্যে সময়কালকে দুর্দান্তভাবে ফর্ম্যাট করে। আমার ব্যবহারের ক্ষেত্রে এটি প্রত্যাশার মতো।
অড্রিয়াস মেসকাউকাস

123

আমি অ্যাপাচি সাধারণের সময়কালীন ফর্ম্যাটগুলি ব্যবহার করি :

DurationFormatUtils.formatDuration(millis, "**H:mm:ss**", true);

13
সহজতম উপায় (অ্যাপাচি কমন্স স্টাইলে)। আপনার এমনকি ফর্ম্যাটডিউরেশনএইচএমএস পদ্ধতি রয়েছে যা আপনি সম্ভবত বেশিরভাগ সময় ব্যবহার করবেন।
মার্কো


29

জাভা ৯ এর পর থেকে এটি সহজ A এ Durationএখনও বিন্যাসযোগ্য নয়, তবে ঘন্টা, মিনিট এবং সেকেন্ড পাওয়ার পদ্ধতিগুলি যুক্ত করা হয় যা কাজটিকে কিছুটা সোজা করে তোলে:

    LocalDateTime start = LocalDateTime.of(2019, Month.JANUARY, 17, 15, 24, 12);
    LocalDateTime end = LocalDateTime.of(2019, Month.JANUARY, 18, 15, 43, 33);
    Duration diff = Duration.between(start, end);
    String hms = String.format("%d:%02d:%02d", 
                                diff.toHours(), 
                                diff.toMinutesPart(), 
                                diff.toSecondsPart());
    System.out.println(hms);

এই স্নিপেট থেকে আউটপুট হয়:

24:19:21


26
long duration = 4 * 60 * 60 * 1000;
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault());
log.info("Duration: " + sdf.format(new Date(duration - TimeZone.getDefault().getRawOffset())));

14
Hah! এই পদ্ধতিটি ব্যবহার করার সময় কেবলমাত্র সময় অঞ্চল স্বাভাবিককরণের সাথে প্রাচীরটিকে আঘাত করুন। ফাংশনটি sdf.setTimeZone(TimeZone.getTimeZone("GMT+0"));ব্যবহার করার আগে আপনাকে যুক্ত করতে formatহবে।
রাজিশ

7

এটি হ্যাকির মতো হতে পারে তবে জাভা 8 এর সাহায্যে কেউ যদি এটি সম্পাদন করতে আগ্রহী হয় তবে এটি একটি ভাল সমাধান java.time:

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.time.temporal.TemporalField;
import java.time.temporal.UnsupportedTemporalTypeException;

public class TemporalDuration implements TemporalAccessor {
    private static final Temporal BASE_TEMPORAL = LocalDateTime.of(0, 1, 1, 0, 0);

    private final Duration duration;
    private final Temporal temporal;

    public TemporalDuration(Duration duration) {
        this.duration = duration;
        this.temporal = duration.addTo(BASE_TEMPORAL);
    }

    @Override
    public boolean isSupported(TemporalField field) {
        if(!temporal.isSupported(field)) return false;
        long value = temporal.getLong(field)-BASE_TEMPORAL.getLong(field);
        return value!=0L;
    }

    @Override
    public long getLong(TemporalField field) {
        if(!isSupported(field)) throw new UnsupportedTemporalTypeException(new StringBuilder().append(field.toString()).toString());
        return temporal.getLong(field)-BASE_TEMPORAL.getLong(field);
    }

    public Duration getDuration() {
        return duration;
    }

    @Override
    public String toString() {
        return dtf.format(this);
    }

    private static final DateTimeFormatter dtf = new DateTimeFormatterBuilder()
            .optionalStart()//second
            .optionalStart()//minute
            .optionalStart()//hour
            .optionalStart()//day
            .optionalStart()//month
            .optionalStart()//year
            .appendValue(ChronoField.YEAR).appendLiteral(" Years ").optionalEnd()
            .appendValue(ChronoField.MONTH_OF_YEAR).appendLiteral(" Months ").optionalEnd()
            .appendValue(ChronoField.DAY_OF_MONTH).appendLiteral(" Days ").optionalEnd()
            .appendValue(ChronoField.HOUR_OF_DAY).appendLiteral(" Hours ").optionalEnd()
            .appendValue(ChronoField.MINUTE_OF_HOUR).appendLiteral(" Minutes ").optionalEnd()
            .appendValue(ChronoField.SECOND_OF_MINUTE).appendLiteral(" Seconds").optionalEnd()
            .toFormatter();

}

আমি শুধু এই চেষ্টা, এবং আমি লক্ষ্য করেছি যে, আমি যদি "HH: MM: SS" জন্য বিন্যাস নামক আমি হয়নি কোনো ঘন্টা বা ফরম্যাট (যেমন মিনিট আছে Duration.ofSeconds(20)), তারপর আমি একটা পেতে চাই UnsupportedTemporalTypeException)। পার্থক্য আছে কিনা তা আমি কেবল কোড চেকিং সরিয়ে ফেলেছি == 01। আমি অনুভব করলাম 01এমন এক ধরণের মাস্কিং মান যা আমি পুরোপুরি বুঝতে পারি না, আপনি কি এটি ব্যাখ্যা করতে পারেন?
গ্রোস্টভ

এটি আসলে খুব ভাল কাজ করেছে। আমার ক্ষেত্রে আমি এমনকি মিলিসেকেন্ড যুক্ত করেছি ... isSupportedপদ্ধতিটি সম্পর্কিত তথ্যটি ফিরিয়ে দেওয়া যদি মানুষের পাঠযোগ্য স্ট্রিংয়ের জন্য কোনও বৈধ ক্ষেত্র থাকে তবে returning যাইহোক "মাস্কিং" আসলে মুখোশ নয়। কোডটি দেখায় return value!=0lনা return value!=01। দয়া করে পরের বার কপি-পেস্ট ব্যবহার করুন।
মিঃ জেমস

1
ইন্টারফেসটি TemporalAccessorস্থিতির জন্য অপব্যবহারের কথা নয়। জেএসআর -310 TemporalAmountএই উদ্দেশ্যে ইন্টারফেসটি ডিজাইন করেছে ।
মেনো হচসচাইল্ড

1
আমি আপনাকে সর্বদা Lএকটি longমান নির্দেশ করার জন্য বড় হাতের অক্ষর ব্যবহার করার পরামর্শ দিই । lঅঙ্ক 1 এর জন্য ছোট ছোট অক্ষরগুলি পড়া এত সহজ , ঠিক যেমন প্রদর্শিত হয়েছে।
ওলে ভিভি

6

কীভাবে সময়কাল ফর্ম্যাট করবেন তা আরও একটি নমুনা এখানে। নোট করুন যে এই নমুনাটি ইতিবাচক সময়কাল হিসাবে ধনাত্মক এবং নেতিবাচক সময়কাল উভয়ই দেখায়।

import static java.time.temporal.ChronoUnit.DAYS;
import static java.time.temporal.ChronoUnit.HOURS;
import static java.time.temporal.ChronoUnit.MINUTES;
import static java.time.temporal.ChronoUnit.SECONDS;

import java.time.Duration;

public class DurationSample {
    public static void main(String[] args) {
        //Let's say duration of 2days 3hours 12minutes and 46seconds
        Duration d = Duration.ZERO.plus(2, DAYS).plus(3, HOURS).plus(12, MINUTES).plus(46, SECONDS);

        //in case of negative duration
        if(d.isNegative()) d = d.negated();

        //format DAYS HOURS MINUTES SECONDS 
        System.out.printf("Total duration is %sdays %shrs %smin %ssec.\n", d.toDays(), d.toHours() % 24, d.toMinutes() % 60, d.getSeconds() % 60);

        //or format HOURS MINUTES SECONDS 
        System.out.printf("Or total duration is %shrs %smin %sec.\n", d.toHours(), d.toMinutes() % 60, d.getSeconds() % 60);

        //or format MINUTES SECONDS 
        System.out.printf("Or total duration is %smin %ssec.\n", d.toMinutes(), d.getSeconds() % 60);

        //or format SECONDS only 
        System.out.printf("Or total duration is %ssec.\n", d.getSeconds());
    }
}

5

এই উত্তরটি কেবল Durationপদ্ধতিগুলি ব্যবহার করে এবং জাভা 8 এর সাথে কাজ করে:

public static String format(Duration d) {
    long days = d.toDays();
    d = d.minusDays(days);
    long hours = d.toHours();
    d = d.minusHours(hours);
    long minutes = d.toMinutes();
    d = d.minusMinutes(minutes);
    long seconds = d.getSeconds() ;
    return 
            (days ==  0?"":days+" jours,")+ 
            (hours == 0?"":hours+" heures,")+ 
            (minutes ==  0?"":minutes+" minutes,")+ 
            (seconds == 0?"":seconds+" secondes,");
}

4

নিম্নলিখিত ফাংশনটি সম্পর্কে কীভাবে হয়, যা হয় + এইচ: এমএম: এসএস বা + এইচ: এমএম: এসএসএসএসকে দেয় returns

public static String formatInterval(final long interval, boolean millisecs )
{
    final long hr = TimeUnit.MILLISECONDS.toHours(interval);
    final long min = TimeUnit.MILLISECONDS.toMinutes(interval) %60;
    final long sec = TimeUnit.MILLISECONDS.toSeconds(interval) %60;
    final long ms = TimeUnit.MILLISECONDS.toMillis(interval) %1000;
    if( millisecs ) {
        return String.format("%02d:%02d:%02d.%03d", hr, min, sec, ms);
    } else {
        return String.format("%02d:%02d:%02d", hr, min, sec );
    }
}

4

কমপক্ষে ২৪ ঘণ্টারও কম সময়কালের জন্য এখানে মোটামুটি সহজ এবং (আইএমও) মার্জিত পদ্ধতির উপস্থিতি রয়েছে:

DateTimeFormatter.ISO_LOCAL_TIME.format(value.addTo(LocalTime.of(0, 0)))

ফর্ম্যাটগুলির ফর্ম্যাট করার জন্য একটি টেম্পোরাল অবজেক্টের প্রয়োজন হয়, তাই আপনি 00:00 এর স্থানীয় সময়কালে (অর্থাত মধ্যরাত) সময়কাল যুক্ত করে একটি তৈরি করতে পারেন। এটি আপনাকে মধ্যরাত থেকে সেই সময়কালের জন্য একটি লোকালটাইম প্রদান করবে যা স্ট্যান্ডার্ড এইচএইচ: মিমি: এসএস সংকেতে ফর্ম্যাট করা সহজ। এটিতে কোনও বাহ্যিক গ্রন্থাগারের প্রয়োজন না পড়ার সুবিধা রয়েছে এবং ঘন ঘণ্টা, মিনিট এবং সেকেন্ডে ম্যানুয়ালি গণনা করার পরিবর্তে গণনা করার জন্য জাভা.টাইম লাইব্রেরি ব্যবহার করে।


3

এটি একটি কার্যকরী বিকল্প।

public static String showDuration(LocalTime otherTime){          
    DateTimeFormatter df = DateTimeFormatter.ISO_LOCAL_TIME;
    LocalTime now = LocalTime.now();
    System.out.println("now: " + now);
    System.out.println("otherTime: " + otherTime);
    System.out.println("otherTime: " + otherTime.format(df));

    Duration span = Duration.between(otherTime, now);
    LocalTime fTime = LocalTime.ofNanoOfDay(span.toNanos());
    String output = fTime.format(df);

    System.out.println(output);
    return output;
}

পদ্ধতিটি সাথে কল করুন

System.out.println(showDuration(LocalTime.of(9, 30, 0, 0)));

এরকম কিছু উত্পাদন করে:

otherTime: 09:30
otherTime: 09:30:00
11:31:27.463
11:31:27.463

2
এটি 23: 59: 59.999 এর চেয়ে বড় সময়ের জন্য ব্যর্থ হবে।
মিশেল জং

2
String duration(Temporal from, Temporal to) {
    final StringBuilder builder = new StringBuilder();
    for (ChronoUnit unit : new ChronoUnit[]{YEARS, MONTHS, WEEKS, DAYS, HOURS, MINUTES, SECONDS}) {
        long amount = unit.between(from, to);
        if (amount == 0) {
            continue;
        }
        builder.append(' ')
                .append(amount)
                .append(' ')
                .append(unit.name().toLowerCase());
        from = from.plus(amount, unit);
    }
    return builder.toString().trim();
}

0

আমার লাইব্রেরি টাইম 4 জ একটি প্যাটার্ন-ভিত্তিক সমাধান সরবরাহ করে (অনুরূপ Apache DurationFormatUtils, তবে আরও নমনীয়):

Duration<ClockUnit> duration =
    Duration.of(-573421, ClockUnit.SECONDS) // input in seconds only
    .with(Duration.STD_CLOCK_PERIOD); // performs normalization to h:mm:ss-structure
String fs = Duration.formatter(ClockUnit.class, "+##h:mm:ss").format(duration);
System.out.println(fs); // output => -159:17:01

এই কোডটি ঘন্টা ওভারফ্লো এবং সাইন হ্যান্ডলিং পরিচালনা করার ক্ষমতাগুলি প্রদর্শন করে , প্যাটার্নের ভিত্তিতে পিরিয়ড-ফর্ম্যাটারের এপিআইও দেখুন ।


0

স্কেলে (আমি অন্য কয়েকটি প্রচেষ্টা দেখেছি, এবং প্রভাবিতও হয়নি):

def formatDuration(duration: Duration): String = {
  import duration._ // get access to all the members ;)
  f"$toDaysPart $toHoursPart%02d:$toMinutesPart%02d:$toSecondsPart%02d:$toMillisPart%03d"
}

ভয়াবহ লাগছে হ্যাঁ? ওয়েল এজন্য আমরা এই স্টাফটি লিখতে আইডিই ব্যবহার করি যাতে পদ্ধতি কলগুলি ( $toHoursPartইত্যাদি) আলাদা রঙ হয় are

f"..."একটি হল printf/ String.formatশৈলী স্ট্রিং প্রক্ষেপক (যা কি দেয় $একজন আউটপুট দেওয়া কাজ কোড ইনজেকশন) 1 14:06:32.583, fইন্টারপোলেট স্ট্রিং সমতূল্য হবেString.format("1 %02d:%02d:%02d.%03d", 14, 6, 32, 583)


0

এই ফানক ব্যবহার

private static String strDuration(long duration) {
    int ms, s, m, h, d;
    double dec;
    double time = duration * 1.0;

    time = (time / 1000.0);
    dec = time % 1;
    time = time - dec;
    ms = (int)(dec * 1000);

    time = (time / 60.0);
    dec = time % 1;
    time = time - dec;
    s = (int)(dec * 60);

    time = (time / 60.0);
    dec = time % 1;
    time = time - dec;
    m = (int)(dec * 60);

    time = (time / 24.0);
    dec = time % 1;
    time = time - dec;
    h = (int)(dec * 24);
    
    d = (int)time;
    
    return (String.format("%d d - %02d:%02d:%02d.%03d", d, h, m, s, ms));
}

এই ফাংশনটির প্যাকেজযুক্ত সংস্করণটি পেতে github.com/ipserc/duration এ যান
ipserc

-1

স্কালায়, আপনার বেস্টবেটের সমাধান তৈরি করা কিন্তু সরলীকৃত:

def prettyDuration(seconds: Long): List[String] = seconds match {
  case t if t < 60      => List(s"${t} seconds")
  case t if t < 3600    => s"${t / 60} minutes" :: prettyDuration(t % 60)
  case t if t < 3600*24 => s"${t / 3600} hours" :: prettyDuration(t % 3600)
  case t                => s"${t / (3600*24)} days" :: prettyDuration(t % (3600*24))
}

val dur = prettyDuration(12345).mkString(", ") // => 3 hours, 25 minutes, 45 seconds

-2

স্কেলে, কোনও লাইব্রেরির প্রয়োজন নেই:

def prettyDuration(str:List[String],seconds:Long):List[String]={
  seconds match {
    case t if t < 60 => str:::List(s"${t} seconds")
    case t if (t >= 60 && t< 3600 ) => List(s"${t / 60} minutes"):::prettyDuration(str, t%60)
    case t if (t >= 3600 && t< 3600*24 ) => List(s"${t / 3600} hours"):::prettyDuration(str, t%3600)
    case t if (t>= 3600*24 ) => List(s"${t / (3600*24)} days"):::prettyDuration(str, t%(3600*24))
  }
}
val dur = prettyDuration(List.empty[String], 12345).mkString("")

3
এটি স্কালার দুর্দান্ত বিজ্ঞাপন নয়? কোনও লাইব্রেরির দরকার নেই, তবে ঠিক ততটাই কোড ...?
আদম

আমি রিকার্সিভ পদ্ধতির মত, কিন্তু এটা অনেক সরলীকৃত করা যেতে পারে: stackoverflow.com/a/52992235/3594403
dpoetzsch

-2

আমি এটি দেখিনি তাই আমি ভেবেছিলাম এটি যুক্ত করব:

Date started=new Date();
SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");
task
long duration=new Date().getTime()-started.getTime();
System.out.println(format.format(new Date(duration));

এটি কেবল 24 ঘন্টা কাজ করে তবে আমি সাধারণত সময়কালের জন্য এটি চাই।

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