Abschluss der Arbeitswoche

8

Ich arbeite einen Standard neun bis fünf. Montag bis Freitag. Ich nehme mir eine halbe Stunde Zeit zum Mittagessen von 12:30 bis 13:00 Uhr.

Schreiben Sie mir ein Programm, das beim Ausführen den Prozentsatz der Arbeitswoche berechnet, den ich zum aktuellen Zeitpunkt abgeschlossen habe.

Regeln

  • Zählen Sie nur die tatsächlich geleistete Arbeitszeit. Ich bin pünktlich und arbeite nicht beim Mittagessen.
  • Keine Eingabe. Sie können Informationen wie die aktuelle Uhrzeit / das aktuelle Datum erhalten, dies ist jedoch zweckmäßig.
  • Die Arbeitswoche gilt vom Freitagende bis Mitternacht zwischen Sonntag und Montag als abgeschlossen.
  • Zeitzone ist die lokale Zeitzone.
  • Die Ausgabe sollte eine Dezimalzahl sein, z. B. 66.25498, Prozentzeichen optional.
  • Das Programm sollte einigermaßen zukunftssicher sein. Es sollte in der Lage sein, Schaltjahre zu bewältigen.
  • Die Ausgabeauflösung sollte eine Sekunde oder besser sein. Ich mag es, den Wasserkocher kochen zu sehen.
  • Code Golf. Der kürzeste Code gewinnt.
skeevey
quelle
1
Was ist deine Zeitzone? System lokal? MITTLERE GREENWICH-ZEIT? Oh, und ist das Mitternacht zwischen Samstag und Sonntag oder Sonntag und Montag?
Ilmari Karonen
Ich habe die Regeln aktualisiert. Ortszeit und Sonntag / Montag Mitternacht.
Skeevey
Verdienen Sie in der Mittagspause Löhne?
DavidC
Ich glaube nicht, dass das einen Unterschied machen würde?
Skeevey
Wenn Sie beim Mittagessen sind, arbeiten Sie nicht, daher
schätze

Antworten:

4

Q, 111 102

0|100*("i"$(27000000*((.z.d)mod 7)-2)+{0|((17:00:00&x)-09:00:00)-0|00:30:00&x-12:30:00}.z.t)%135000000
tmartin
quelle
5

Python 3, 132

from datetime import*
t=datetime.now().timetuple()
m=max(0,t[3]*2+t[4]/30-18)
print(20*min(5,(t[6]+min(15,m-min(8,max(7,m))+7)/15)))

Die Auflösung beträgt eine Minute oder 2/45 Prozent. Das ist mehr als genug IMO.

Fraxtil
quelle
5

Excel, 132 , 129 , 123 , 119 , 117

Einfügen in A2: A4

=NOW()
=A2-INT(A2)-.375
=(WEEKDAY(A2,3)*7.5+IF(A3<0,0,IF(A3>TIME(8,0,0),7.5,(A3-IF(A3>.1875,TIME(0,30,0),0))*24)))/37.5

Formatieren Sie die Zelle A4 als%, um das richtige Format zu erhalten

40 Stunden Arbeitswoche - Bezahltes Mittagessen:

88 , 81

=NOW()
=A1-INT(A1)-.375
=(WEEKDAY(A1,3)*8+IF(A2<0,0,IF(A2>TIME(8,0,0),8,A2*24)))/40
SeanC
quelle
Die erste scheint nicht zu funktionieren, wenn NOW()es eine Zeit nach 17 Uhr ist.
Gaffi
augh - a * 24 in der falschen Position .....
SeanC
:-) Übrigens, gute Arbeit, mich bei meinem VBA-Ansatz zu übertreffen, indem ich stattdessen Formeln verwende. Jetzt wähle ich nicht ... Ihr Update hat ein char ( 0) hinzugefügt , das nicht notwendig ist!
Gaffi
Meine Entschuldigung ist, dass ich nach 5:00 eine ganze Weile nicht mehr bei der Arbeit war: D
SeanC
2

Perl, 124 Zeichen

OK, einfache erste Lösung zum Setzen des Par:

say(($p=((($s,$m,$h,@t)=localtime)[6]+6)%7*20+(($h+=$m/60+$s/3600-9)<0?0:$h<3.5?$h:$h<4?3.5:$h<8?$h-.5:7.5)*8/3)<100?$p:100)

Führen Sie mit aus perl -M5.010, um die Perl 5.10+ say-Funktion zu aktivieren . Die Auflösung beträgt eine Sekunde. Wenn eine Auflösung von einer Minute akzeptabel ist, kann das +$s/3600Teil für eine Gesamtlänge von 116 Zeichen gelöscht werden .

Diese Lösung verwendet localtime, um den Wochentag und die Tageszeit zu ermitteln. Sie sollte daher unabhängig von Jahresänderungen, Schalttagen oder anderen Besonderheiten des Kalenders funktionieren, zumindest solange sich der Zyklus der Woche mit sieben Tagen nicht ändert. Änderungen der Sommerzeit während des Arbeitstages würden es leicht verwirren, aber diese treten im Grunde sowieso nie auf, vermutlich gerade deshalb, weil dies zu viel Verwirrung führen würde.

(Beachten Sie zum Testen, dass localtimeein Unix-Zeitstempel als optionales Argument akzeptiert wird.)

Ilmari Karonen
quelle
2

Mathematica 169 168 212 214 211 218 210 190 Zeichen

Langatmig, nach Code Golf Standards.

Im Folgenden werden Arbeitswochen berücksichtigt, die Monats- oder Jahresgrenzen überschreiten, sowie Schaltjahre. Die Arbeitszeit wird nach Stunden und Minuten berechnet.

Ich konnte mir keinen Weg vorstellen, die Wochentage nicht zu buchstabieren. Mathematica gibt den Wochentag als 3-stellige Zeichenfolge zurück, die in eine Zahl umgewandelt werden muss.

h = Plus @@ {#1, #2/60, #3/3600} & @@ Take[DateList[], -3]; 100*Min[37.5, (StringTake[DateString[], 3] /. {"Mon" -> 0, "Tue" -> 1, "Wed" -> 2 , "Thu" -> 3, "Fri" -> 4, _ -> 5})*7.5 + Which[h < 12.5, Max[0, h - 9], h < 13, 4, True, 4 + Min[h - 13, 4]]]/37.5

De-Golf gespielt

(* d returns {year, mo, day, h, m, s}   *)
d = DateList[]

(* finished Days: hours worked *)
f = (StringTake[DateString[],  3] /. {"Mon" -> 0, "Tue" -> 1, "Wed" -> 2 , "Thu" -> 3, "Fri" -> 4, _ -> 5})*7.5

(* time of day in hours *)
h = Plus @@ {#1, #2/60} & @@ Take[d, -3]

(* today: hours Worked. It also computes hours for Sat and Sunday but does not use 
them in the final tabulation, which has a maximum of 37.5. *)
t = Which[h < 12.5, Max[0, h - 9], h < 13, 4, _, 4 + Min[h - 13, 4]]

(* hours Worked in week *)
tot = Min[37.5, f + t]

(* % of working week completed *)
100*tot/37.5

Arbeitswoche

DavidC
quelle
2

VBA 141

Formatiert, um aus dem unmittelbaren Fenster ausgeführt zu werden. Vielen Dank an Sean Cheshire für den Hinweis auf eine Verbesserung um 10 Zeichen!

n=(Now-Int(Now))*24:a=(Weekday(Now,3)*7.5+IIf(n>17,7.5,IIf(n>9,IIf(n<12.5,n,IIf‌​(n>13,n-.5,n))-9,0)))/37.5:MsgBox Format(IIf(a>1,1,a),".0%")
Gaffi
quelle
Verwenden Sie n = n * 24, und es kann weiter reduziert werden. Mein Kampf damit n=(Now-Int(Now))*24:a=(Weekday(Now,3)*7.5+IIf(n>17,7.5,IIf(n>9,IIf(n<12.5,n,IIf(n>13,n-.5,n))-9,0)))/37.5:MsgBox Format(IIf(a>1,1,a),".0%")
ergab Folgendes
@ SeanCheshire Ausgezeichneter Punkt! Meine Methode hatte eine übrig gebliebene Syntax aus einer früheren Version, die n verwendete, sodass sie nicht geändert werden konnte.
Gaffi
1

R, 115 Zeichen

---------1---------2---------3---------4---------5---------6---------7---------8---------9---------0---------1---------2
T=as.POSIXlt(Sys.time()-86400);z=T$h+T$mi/60-9;D=function(x,M)min(M,max(0,x));D(((D(z,8)-D(z-3.5,.5))/7.5+T$w)/5,1)

Hier ist eine einwöchige Simulation:

week.frac <- function(t) {
   T <- as.POSIXlt(t-86400)
   z <- T$h+T$mi/60-9
   D <- function(x,M)min(M,max(0,x))
   D(((D(z,8)-D(z-3.5,.5))/7.5+T$w)/5,1)
}

time <- seq(from = as.POSIXlt(as.Date("2012-08-20")),
            to   = as.POSIXlt(as.Date("2012-08-27")),
            by   = "min")
week.completion <- sapply(time, week.frac)
plot(time, week.completion, type = "l")

Wochenabschluss für die aktuelle Woche

flodel
quelle
1

Ruby, 191, 116 , 115, 113

Die Logik wird aus der Fraxtils Python-Lösung gestohlen .

t=Time.now
d=t.wday
m=[0,t.hour*2+t.min/3e1-18].max
p d<1?100:20*[5,(d-1+[15,m-[8,[7,m].max].min+7].min/15)].min

Wenn Sie den Code mit dem Komponententest testen möchten, benötigen Sie diese 143-Zeichen-Lösung:

class Time  
def r
m=[0,hour*2+min/3e1-18].max
d=wday
d<1?100:20*[5,(d-1+[15,m-[8,[7,m].max].min+7].min/15)].min
end    
end
p Time.now.r

Nicht der kürzeste und effizienteste Code, aber mit einem Unit-Test;)

Die 191 Zeichen enthalten die Zeilenumbrüche (ich könnte es zu einem Einzeiler machen, ersetzen Sie einfach jeden Zeilenumbruch durch einen ;).

class Time
def r
i=0
d{|t|i+=t.w}
i/1350.0
end
def d
t=dup
yield t-=1 until t.strftime('%w%T')=='109:00:00'
end
def w
h=hour
wday<1||wday>5||h<9||h>16||h==12&&min>29?0:1
end
end
p Time.now.r

Und der Testcode:

require 'test/unit'
class MyTest < Test::Unit::TestCase
  def test_mo
    assert_equal( 20, Time.new(2012,8,13,20).r) #monday
  end
  def test_tue
    assert_equal( 40, Time.new(2012,8,14,20).r) #tuesday
  end
  def test_wed_morning
    assert_equal( 40, Time.new(2012,8,15,7).r)
  end
  def test_wed
    assert_equal( 60, Time.new(2012,8,15,20).r)
  end
  def test_thu
    assert_equal( 80, Time.new(2012,8,16,20).r)
  end
  def test_fri
    assert_equal(100, Time.new(2012,8,17,20).r)
  end
  def test_sat
    assert_equal(100, Time.new(2012,8,18,20).r)
  end
  def test_sun
    assert_equal(100, Time.new(2012,8,19,20).r)
  end
  def test_middle
    assert_equal(50, Time.new(2012,8,15,13,15).r)
  end
end
knut
quelle
0

Python 2 130 Zeichen

from datetime import*
t=datetime.now().timetuple();
m=min
a=max
n=t[3]+t[4]/60.0
print m(17,a(9,n))-9-(a(0,m(.5,n-12.5)))+7.5*m(t[6],4)

Mein dritter Versuch ist eine schwache Sauce, aber ich glaube, ich habe die Logik richtig verstanden.

Chucksmash
quelle
1
Das funktioniert nicht. Auf einen kurzen Blick auf die Ausgabe gibt es keine langen Zeiträume, in denen der Prozentsatz gleich bleibt. Dies sollte zwischen 17:00 Uhr und 9:00 Uhr am nächsten Tag sowie zwischen 12:30 Uhr der Fall sein -1: 00 PM Intervall. Es werden auch manchmal negative Zahlen und Zahlen größer als 100 ausgegeben.
Fraxtil
Oh, schäme dich für mich. Du hast absolut recht. Mulligan.
Chuckmash
@Fraxtil Ich glaube, ich habe dich um ein Haar
verdrängt
Dies scheint einen Bereich von 0 bis 37,5 zu haben. Es wird jedoch in den entsprechenden Intervallen angehalten.
Fraxtil
Oh, ich hatte es so eingestellt, dass die Anzahl der Stunden für das Debuggen ausgedruckt wurde. Ich habe vergessen, es zur Beantwortung auf% umzustellen. Ich schätze, ich werde das nicht in 2 Charakteren machen können, also hast du mich wohl doch bekommen
Chuckmash