আমি জাভাতে কীভাবে "সুন্দর মুদ্রণ" করতে পারি?


95

এমন কোনও জাভা লাইব্রেরি কি কেউ জানেন যা সি # তে একইভাবে একাধিক মিলি সেকেন্ডে মুদ্রণ করতে পারে?

উদাহরণস্বরূপ, দীর্ঘ হিসাবে 123456 এমএস 4d1h3m5 এস হিসাবে মুদ্রিত হবে।


4
অবগতির জন্য, বিন্যাস আপনি মনে বর্ণনা করা একটি করা হয় Durationযুক্তিসম্মত মান সংজ্ঞায়িত, আইএসও 8601 : PnYnMnDTnHnMnSযেখানে Pমানে হলো "সময়কাল" এবং চিহ্ন শুরুতে Tসময় অংশ থেকে তারিখ অংশ আলাদা করে, এবং এর মধ্যে একটি একক সঙ্গে একটি সংখ্যা ঐচ্ছিক occurrances হয় লেটার সংক্ষেপণ উদাহরণস্বরূপ, PT4H30M= সাড়ে চার ঘন্টা।
তুলিল বাউর্ক

4
অন্য সমস্ত কিছু যদি ব্যর্থ হয় তবে এটি নিজে করা খুব সাধারণ বিষয়। একের পর এক অ্যাপ্লিকেশন ব্যবহার করুন %এবং /সংখ্যাটি অংশগুলিতে বিভক্ত করুন। প্রস্তাবিত উত্তরগুলির চেয়ে প্রায় সহজ।
হট লিক্স

@HotLicks অনেক পরিষ্কার এবং ব্যবহার না করে পরিষ্কার কোডের জন্য গ্রন্থাগার পদ্ধতি এটা ত্যাগ /এবং %
ওলে ভিভি

হ্যাঁ, মধ্যবর্তী আট বছরে আমি এই প্রশ্নটি জিজ্ঞাসা করার পরে (!) আমি জোদা সময়ের দিকে চলে এসেছি যা আমার ব্যবহারের ক্ষেত্রে খুব ভালভাবে স্যুট করে
ফ্যাটম্যান্স

@phatmanace Joda-টাইম প্রকল্পের রক্ষণাবেক্ষণ-মোড মধ্যে এখন হয়, এবং মাইগ্রেশন উপদেশ java.time জাভা 8 এবং পরে পাতাটা ক্লাস।
তুলিল বাউরক

উত্তর:


91

একটি পিরিয়ডফর্মেটর বিল্ডার ব্যবহার করে জোদা টাইমের খুব ভাল উপায় আছে ।

দ্রুত জয়: PeriodFormat.getDefault().print(duration.toPeriod());

যেমন

//import org.joda.time.format.PeriodFormatter;
//import org.joda.time.format.PeriodFormatterBuilder;
//import org.joda.time.Duration;

Duration duration = new Duration(123456); // in milliseconds
PeriodFormatter formatter = new PeriodFormatterBuilder()
     .appendDays()
     .appendSuffix("d")
     .appendHours()
     .appendSuffix("h")
     .appendMinutes()
     .appendSuffix("m")
     .appendSeconds()
     .appendSuffix("s")
     .toFormatter();
String formatted = formatter.print(duration.toPeriod());
System.out.println(formatted);

4
এটি নীচে একটি উত্তর থেকে উপস্থিত হয় যে প্রথম সময়কালের উদাহরণ তৈরি না করে এবং তারপরে এটি পিরিয়ডে রূপান্তর না করেই পিরিয়ডের একটি উদাহরণ সরাসরি তৈরি করা যায়। যেমন পিরিয়ড পিরিয়ড = নতুন পিরিয়ড (মিলিস); স্ট্রিং বিন্যাসিত = formatter.print (সময়কাল);
তুলসী ভ্যান্ডেগ্রেন্ড

7
এই "সময়কাল। টু পিরিয়ড ()" রূপান্তর সম্পর্কে সাবধান থাকুন। যদি সময়কালটি বেশ বড় হয় তবে দিনের অংশটি 0 হিসাবে থাকবে hours ঘন্টা অংশটি বাড়তে থাকবে। আপনি 25h10m23s পাবেন তবে কখনই "d" পাবেন না। কারণটি হ'ল জোদার কঠোর উপায়ে ঘন্টাগুলিকে দিনের মধ্যে রূপান্তর করার কোনও সঠিক সঠিক উপায় নেই। বেশিরভাগ ক্ষেত্রে, আপনি যদি দুটি তাত্ক্ষণিকের তুলনা করছেন এবং এটি মুদ্রণ করতে চান, আপনি নতুন সময়কাল (টি 1, টি 2) .toPeriod () এর পরিবর্তে নতুন পিরিয়ড (টি 1, টি 2) করতে পারেন।
বুন

@ আপনি কি জানেন যে কীভাবে সময়ের সাথে সময়কালে রূপান্তর করতে হয়? আমি সময়কালটি ব্যবহার করি যা থেকে আমার টাইমারটিতে আমার দ্বিতীয় স্থান পেতে পারে। ইভেন্ট সেটিং PeriodType.daysTime()বা .standard()সহায়তা করে নি
মেরিট করুন

4
@ মুর্ট আপনি যদি সত্যিই চান এবং কোনও দিনের মানক সংজ্ঞাটি গ্রহণ করতে পারেন তবে উপরের কোডটিতে আপনি "ফরম্যাটার.প্রিন্ট (পিরিয়ড। টু পিরিওড ()। নরমালাইজড স্ট্যান্ডার্ড ())" করতে পারেন। আনন্দ কর!
বুন

78

আমি জাভা 8 এর Duration.toString()এবং কিছুটা রেইগেক্স ব্যবহার করে একটি সহজ সমাধান তৈরি করেছি :

public static String humanReadableFormat(Duration duration) {
    return duration.toString()
            .substring(2)
            .replaceAll("(\\d[HMS])(?!$)", "$1 ")
            .toLowerCase();
}

ফলাফলটি দেখতে পাবেন:

- 5h
- 7h 15m
- 6h 50m 15s
- 2h 5s
- 0.1s

আপনি যদি এর মধ্যে শূন্যস্থান না চান তবে কেবল সরিয়ে দিন replaceAll


6
আপনি কখনও স্ট্রং () এর আউটপুট উপর নির্ভর করবেন না কারণ এটি আরও সংস্করণে পরিবর্তিত হতে পারে।
ওয়েলট্রামস্যাফ

14
@ ওয়েলট্রামস্যাফ এটি পরিবর্তনের সম্ভাবনা নেই, যেহেতু এটি জাভাডকে নির্দিষ্ট করা হয়েছে
অ্যাডিটসু ছাড়ুন কারণ এসই ইভিল

9
@ ওয়েলট্রামাসাফ সুস্পষ্টভাবে Duration::toStringসংজ্ঞায়িত এবং সুসজ্জিত আইএসও 8601 স্ট্যান্ডার্ড অনুসারে আউটপুট ফর্ম্যাট হওয়ার কারণে পরিবর্তন করা অসম্ভব ।
তুলসী বাউরক

4
আপনি যদি ভগ্নাংশ চান না, .replaceAll("\\.\\d+", "")কল করার আগে যুক্ত করুন toLowerCase()
zb226

4
@ ওয়েলট্রামস্যাফ আপনার বক্তব্যটি সাধারণভাবে সঠিক এবং আমি নিজেই বেশিরভাগ ক্লাসের টস্ট্রিং () আউটপুটে ভরসা রাখি না। তবে এই খুব নির্দিষ্ট ক্ষেত্রে, পদ্ধতির সংজ্ঞাটি জানিয়েছে যে এর আউটপুটটি ISO-8601 স্ট্যান্ডার্ড অনুসরণ করে, যেমন আপনি পদ্ধতির জাভাদোক দেখতে পাচ্ছেন । সুতরাং এটি বেশিরভাগ ক্লাসের মতো বাস্তবায়নের বিশদ নয়, তাই জাভা হিসাবে পরিপক্ক একটি ভাষাও এর মতো পরিবর্তিত হবে বলে আমি আশা করব না
লুকাশস

13

অ্যাপাচি কমন্স-ল্যাং এটির পাশাপাশি ডিওরেশনফর্ম্যাটU টি ব্যবহার করতে একটি দরকারী ক্লাস সরবরাহ করে

উদাহরণস্বরূপ DurationFormatUtils.formatDurationHMS( 15362 * 1000 ) )=> 4: 16: 02.000 (এইচ: এম: এস.মিলিস) DurationFormatUtils.formatDurationISO( 15362 * 1000 ) )=> পি0 ওয়াইএমএমডিডি 4 এইচ 16 এম 2.000 এস, সিএফ. আইএসও 8601


9

জোডাটাইমের একটি Periodশ্রেণি রয়েছে যা এ জাতীয় পরিমাণ উপস্থাপন করতে পারে IsoPeriodFormatএবং আইএসও 8601 ফর্ম্যাটে (মাধ্যমে ) রেন্ডার করা যেতে পারে PT4D1H3M5S, যেমন

Period period = new Period(millis);
String formatted = ISOPeriodFormat.standard().print(period);

যদি সেই ফর্ম্যাটটি আপনি চান না, তবে PeriodFormatterBuilderআপনাকে আপনার সি #-স্টাইল সহ স্বেচ্ছাসেবক লেআউটগুলি একত্রিত করতে দেয় 4d1h3m5s


4
ঠিক যেমন একটি নোট, ডিফল্টরূপে new Period(millis).toString()ব্যবহার করে ISOPeriodFormat.standard()
থমাস

9

জাভা 8 এর সাহায্যে আপনি আইএসও 8601 সেকেন্ড ভিত্তিক উপস্থাপনা যেমন পিটি 8 এইচ 6 এম 12.345 এস ব্যবহার করে এটি বাহ্যিক লাইব্রেরি ছাড়া বিন্যাস করার toString()পদ্ধতিটিও ব্যবহার করতে পারেন ।java.time.Duration


4
নোট করুন যে এটি দিনগুলি মুদ্রণ করে না
উইম দেবলাউই

60
নিশ্চিত নন এই বিন্যাসে আমার সংজ্ঞা পূরণ করে প্রশংসনীয় মুদ্রণ। :-)
james.garriss

@ james.garriss এটা একটু prettier করতে দেখতে উত্তর erickdeoliveiraleal দ্বারা।
তুলিল বাউরক

8

খাঁটি জেডিকে কোড ব্যবহার করে আপনি এটি কীভাবে করতে পারেন তা এখানে:

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.Duration;

long diffTime = 215081000L;
Duration duration = DatatypeFactory.newInstance().newDuration(diffTime);

System.out.printf("%02d:%02d:%02d", duration.getDays() * 24 + duration.getHours(), duration.getMinutes(), duration.getSeconds()); 

7

org.threeten.extra.AmountFormats.wordBased

ThreeTen-অতিরিক্ত প্রকল্প, যা স্টিফেন Colebourne, JSR 310, লেখক দ্বারা পরিচালিত হয় java.time এবং Joda-টাইম , একটি হয়েছে AmountFormatsবর্গ যেটি মান জাভা 8 তারিখ সময় শ্রেণীর সাথে কাজ করে। এটি আরও কমপ্যাক্ট আউটপুট জন্য কোনও বিকল্প নেই, যদিও মোটামুটি ভার্জোজ।

Duration d = Duration.ofMinutes(1).plusSeconds(9).plusMillis(86);
System.out.println(AmountFormats.wordBased(d, Locale.getDefault()));

1 minute, 9 seconds and 86 milliseconds


4
বাহ, জানতে পেরে, আমি সেই বৈশিষ্ট্যটি দেখিনি। যদিও এর একটি বড় ত্রুটি রয়েছে: অক্সফোর্ড কমাটি মিস করা ।
বাসিল বাউর্ক

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

6

জাভা 9+

Duration d1 = Duration.ofDays(0);
        d1 = d1.plusHours(47);
        d1 = d1.plusMinutes(124);
        d1 = d1.plusSeconds(124);
System.out.println(String.format("%s d %sh %sm %ss", 
                d1.toDaysPart(), 
                d1.toHoursPart(), 
                d1.toMinutesPart(), 
                d1.toSecondsPart()));

2 ডি 1 এইচ 6 এম 4 এস


আপনি কীভাবে "টু আওয়ারস পার্ট" এবং তারপরে পাবেন?
ঘোটি এবং চিপস

5

জোদা-সময়ের বিল্ডার-পদ্ধতির বিকল্প একটি প্যাটার্ন-ভিত্তিক সমাধান হবে । এটি আমার লাইব্রেরি টাইম 4 জে অফার করেছে । ক্লাসের সময়কাল ব্যবহারের উদাহরণ For ফর্ম্যাটর (আরও পঠনযোগ্যতার জন্য কিছু স্পেস যুক্ত করেছে - স্পেসগুলি সরিয়ে কাঙ্ক্ষিত সি #-স্টাইল উপস্থাপন করবে):

IsoUnit unit = ClockUnit.MILLIS;
Duration<IsoUnit> dur = // normalized duration with multiple components
  Duration.of(123456, unit).with(Duration.STD_PERIOD);
Duration.Formatter<IsoUnit> f = // create formatter/parser with optional millis
  Duration.Formatter.ofPattern("D'd' h'h' m'm' s[.fff]'s'");

System.out.println(f.format(dur)); // output: 0d 0h 2m 3.456s

এই ফর্ম্যাটরটি- java.timeএপিআইয়ের সময়কালগুলিও মুদ্রণ করতে পারে (তবে, এই ধরণের সাধারণকরণের বৈশিষ্ট্যগুলি কম শক্তিশালী):

System.out.println(f.format(java.time.Duration.ofMillis(123456))); // output: 0d 0h 2m 3.456s

ওপির প্রত্যাশা যে "123456 এমএস দীর্ঘ হিসাবে 4d1h3m5s হিসাবে মুদ্রিত হবে" স্পষ্টতই ভুল উপায়ে গণনা করা হয়। আমি কারণ হিসাবে opালু অনুমান। উপরে বর্ণিত একই সময়কালের ফর্ম্যাটরটিকেও পার্সার হিসাবে ব্যবহার করা যেতে পারে। নিম্নলিখিত কোডটি দেখায় যে "4d1h3m5s" বরং এর সাথে মিলেছে 349385000 = 1000 * (4 * 86400 + 1 * 3600 + 3 * 60 + 5):

System.out.println(
  f.parse("4d 1h 3m 5s")
   .toClockPeriodWithDaysAs24Hours()
   .with(unit.only())
   .getPartialAmount(unit)); // 349385000

ক্লাসটি ব্যবহার করা হচ্ছে net.time4j.PrettyTime(যা স্থানীয়ভাবে আউটপুট এবং "কাল", "পরের রবিবার", "4 দিন আগে" ইত্যাদির মতো আপেক্ষিক সময়ের মুদ্রণের জন্যও ভাল):

String s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.NARROW);
System.out.println(s); // output: 2m 3s 456ms

s = PrettyTime.of(Locale.ENGLISH).print(dur, TextWidth.WIDE);
System.out.println(s); // output: 2 minutes, 3 seconds, and 456 milliseconds

s = PrettyTime.of(Locale.UK).print(dur, TextWidth.WIDE);
System.out.println(s); // output: 2 minutes, 3 seconds and 456 milliseconds

সংক্ষিপ্তসারগুলি ব্যবহৃত হয় বা না হয় তবে পাঠ্যের প্রস্থ নিয়ন্ত্রণ করে। তালিকার বিন্যাসটি উপযুক্ত লোকেল চয়ন করেও নিয়ন্ত্রণ করা যায়। উদাহরণস্বরূপ, স্ট্যান্ডার্ড ইংরাজী অক্সফর্ম কমা ব্যবহার করে, যখন যুক্তরাজ্য তা করে না। টাইম 4 জের সর্বশেষতম সংস্করণ v5.5 90 টিরও বেশি ভাষাগুলি সমর্থন করে এবং সিএলডিআর-সংগ্রহস্থল (একটি শিল্প মান) এর ভিত্তিতে অনুবাদ ব্যবহার করে uses


4
এই প্রাইটিটাইম অন্য উত্তরের চেয়ে একরকম ভাল! খুব খারাপ আমি এই প্রথম খুঁজে পেল না।
ycomp

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

4

ব্যবহারকারী 678573 এর উত্তরের উপর ভিত্তি করে একটি জাভা 8 সংস্করণ :

private static String humanReadableFormat(Duration duration) {
    return String.format("%s days and %sh %sm %ss", duration.toDays(),
            duration.toHours() - TimeUnit.DAYS.toHours(duration.toDays()),
            duration.toMinutes() - TimeUnit.HOURS.toMinutes(duration.toHours()),
            duration.getSeconds() - TimeUnit.MINUTES.toSeconds(duration.toMinutes()));
}

... যেহেতু জাভা 8 তে কোনও পিরিয়ডফর্ম্যাটর নেই এবং গেটহর্স, গেটমিনেটস, ... এর মতো কোনও পদ্ধতি নেই

আমি জাভা 8 এর জন্য আরও ভাল সংস্করণ দেখে খুশি হব।


java.util.Illegal
FormatConversionException

সময়কাল d1 = Distance.ofDays (0) সহ; d1 = d1.plusHours (47); d1 = d1.plusMinutes (124); d1 = d1.plusSeconds (124); System.out.println (স্ট্রিং. ফর্ম্যাট ("% s দিন এবং% sh% sm% 1.0fs", d1.toDays (), d1.toHours () - টাইমউনিট.ডি.এই.এস.এস.এইচ.এইচ ঘন্টাস (ডি 1. টোডেস ()), ডি 1 .TOMinutes () - টাইমউনিট.এইচওআরএস.টোমিনুটস (d1.toHours ()), ডি 1.টোসেকেন্ডস () - টাইমউনিট.মিনুটস.টোনসেকেন্ডস (ডি 1.টোমিনুটস ())));
এরিকডিওলিভিওরিয়াল

নিবন্ধটি প্রকাশ করার জন্য ধন্যবাদ আমি মনে করি আমি মূলত গ্রোভির জন্য কোডটি লিখছিলাম, সুতরাং এটি সম্ভবত এই ভাষায় কাজ করেছিল। আমি এখন জাভা জন্য এটি সংশোধন।
টর্স্টেন

3

আমি বুঝতে পারি এটি আপনার ব্যবহারের ক্ষেত্রে হুবহু মাপসই নয়, তবে প্রাইটিটাইম এখানে কার্যকর হতে পারে।

PrettyTime p = new PrettyTime();
System.out.println(p.format(new Date()));
//prints: “right now”

System.out.println(p.format(new Date(1000*60*10)));
//prints: “10 minutes from now”

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