Bagaimana cara menggunakan perintah tanggal untuk mengetahui tanggal "Senin minggu 40"?

11

Bagaimana saya bisa menggunakan perintah tanggal untuk mengubah sesuatu seperti "Senin minggu 40" menjadi tanggal ISO?

Saya bermain dengan sesuatu seperti ini:

date --date='monday week 40' +'%Y-%m-%d'

Dan tanggal yang saya cari adalah 2011-10-03.

Tetapi masalah saya adalah bahwa string tanggal ini tidak valid, jadi saya perlu pendekatan lain untuk menyelesaikan masalah ini.

/Terima kasih

Johan
sumber
Tautan berikut adalah tentang apa yang menentukan pada hari apa tahun dimulai suatu minggu bernomor . Penomoran minggu (Wikipedia) .. Secara efektif menjelaskan mengapa tanggal 1 Januari tahun ini di ISO 52 minggu. %VUrutan format yang digunakan oleh 'pengguna tidak diketahui' melaporkan angka minggu ISO.
Peter.O

Jawaban:

4

Sangat jelek dan mungkin hanya berfungsi dengan GNU date:

date -d "$( date -d "$( date +'%Y-01-01' ) +40 weeks") -$( date -d "$( date +'%Y-01-01' ) +40 weeks" +'%w' ) days+1 day" +'%Y-%m-%d'

Diuji hanya untuk contoh 3 Oktober Anda, mungkin gagal untuk beberapa kasus lain.


Pembaruan : Jika Anda memiliki lokal non eng Anda perlu menentukan output dari tanggal batin untuk mulai bekerja. (Dan% F adalah YYYY-MM-DD).

date -d "$(date -d "$(date +'%Y-01-01') +40 weeks" +"%F") -$(date -d "$(date +'%Y-01-01') +40 weeks" +%w) days +1 day" +"%F"
manatwork
sumber
1
Anda tidak memformat output dari tanggal dalam sehingga bagian luar dapat menggunakannya dengan benar.
Johan
@ Johan, saya tidak punya masalah dengan menggunakan format default. Mungkin itu spesifik lokal? Saya menggunakan en_US. Poin yang bagus.
manatwork
Untuk tanggal saya menggunakan lokal Swedia, jadi ada perbedaan.
Johan
Terima kasih atas penyesuaian lokal. Saya memiliki format tanggal khusus dan memiliki masalah yang sama .. Saya hampir menyelesaikannya, tetapi sekarang Anda telah mempostingnya, saya akan menggunakan tweak Anda; lebih baik.
Peter.O
Tidak ada persyaratan untuk ini menjadi satu-liner. Akan lebih baik untuk membaginya menjadi beberapa baris, menggunakan variabel sementara dengan nama deskriptif untuk memperjelas cara kerjanya. Ini juga mengasumsikan bahwa 1 Januari adalah dalam jumlah minggu yang sama setiap tahun, yang tidak seperti yang telah dicatat oleh @ Peter.O.
Adam Spires
5

Pendekatan alternatif:

date --date "+$((40-$(date +%V)))weeks last monday"  +"%F"
  • 40 adalah minggu yang Anda cari
  • date +% V mengembalikan minggu ini (35)
  • 40-35 = 5, yang merupakan jumlah minggu untuk ditambahkan
  • dari sana, cari senin terakhir
Pengguna tidak diketahui
sumber
bagus, dan itu bekerja dengan pengaturan tanggal kustom saya.
Peter.O
Ini ide yang cerdas, tetapi tidak berhasil. Misalnya, jika hari ini adalah Senin di minggu 41 (yaitu date +%Vkembali 41), maka nilai --dateparameter akan menjadi +-1weeks last monday, yang sebenarnya dua minggu yang lalu, bukan 7 hari yang lalu.
Adam Spires
Saya tidak yakin apakah saya memahami kritik Anda. Ini tahun 2013 tahun ini, jadi contoh dari pertanyaan tidak cocok. Apa yang harus menjadi tanggal absolut untuk pertanyaan itu, dan apa yang dikembalikan oleh pendekatan saya (mungkin: mengapa)?
pengguna tidak diketahui
@AdamSpiers: Kalender saya ditampilkan sebagai Senin, minggu 40 tanggal 30 Sep. itulah yang dihasilkan algo saya (hari ini).
pengguna tidak diketahui
@userunknown Itu karena Anda menguji kode Anda hari ini, yang merupakan hari Selasa, yang datang setelah hari Senin. Jika Anda menguji kode Anda kemarin, itu akan rusak. Untuk membuatnya lebih jelas, coba jalankan date -d 'last monday'. Itu akan kembali kemarin. Menurut Anda apa yang akan dikatakan jika Anda menjalankannya kemarin?
Adam Spires
1

Oke, ini usahaku. Ini mencuri ide dari jawaban lain, dan upaya untuk membuat logika lebih mudah diikuti. Ini didasarkan pada sistem ISO 8601, jadi itu tidak benar jika Anda tinggal di negara-negara seperti Amerika Serikat atau Kanada, tetapi harus mudah disesuaikan untuk negara-negara tersebut.

# sets $week_start to a representation of Monday of the given week
# number formatted via the given format, and similarly sets
# $week_end to Friday of the same week.
get_week_range () {
    week_num="$1" date_format="$2"

    # Most of the world adhere to ISO 8601 which states that weeks begin on Monday
    # and Jan 4th is always in week #1:
    #
    #   http://en.wikipedia.org/wiki/ISO_week_date
    #
    # For other week numbering systems (e.g. USA, Canada), see:
    #
    #   http://en.wikipedia.org/wiki/Seven-day_week#Week_numbering
    day_in_week_1=$( date +'%Y-01-04' )
    day_num_in_week_1=$( date -d $day_in_week_1 +%u ) # 1 is Monday
    days_from_week_1_start=$(( $day_num_in_week_1 - 1 ))
    # This is a Monday:
    start_of_week_1=$( date -d "$day_in_week_1 - $days_from_week_1_start days" +%F )

    week_delta="$(( $week_num - 1 ))"
    # Monday:
    week_start=$( date -d "$start_of_week_1 + $week_delta weeks"          +"$date_format" )
    # Friday:
    week_end=$(   date -d "$start_of_week_1 + $week_delta weeks + 4 days" +"$date_format" )
}
Adam Spires
sumber