Вот мое предлагаемое решение, включающее некоторую простую (не идеальную) проверку входных данных. Я поместил решение внутри метода, поэтому запрос пользователя на ввод не обрабатывается
public static void calcTime(String sTimeIn, String sTimeOut) {
final String timePattern = "[0-2][0-9]:[0-5][0-9]";
if (sTimeIn == null || sTimeOut == null || !sTimeIn.matches(timePattern) || !sTimeIn.matches(timePattern)) {
throw new IllegalArgumentException();
}
String[] timeIn = sTimeIn.split(":");
String[] timeOut = sTimeOut.split(":");
int inMinutes = 60 * Integer.valueOf(timeIn[0]) + Integer.valueOf(timeIn[1]);
int outMinutes = 60 * Integer.valueOf(timeOut[0]) + Integer.valueOf(timeOut[1]);
int diff = 0;
if (outMinutes > inMinutes) {
diff = outMinutes - inMinutes;
} else if (outMinutes < inMinutes) {
diff = outMinutes + 24 * 60 - inMinutes;
}
System.out.printf("Time difference between %s and %s is %d hours and %d minutes\n", sTimeIn, sTimeOut, diff / 60, diff % 60);
}
[117 ] Обновление
Вот решение на основе LocalTime
и Duration
public static void calcTime2(String sTimeIn, String sTimeOut) {
final String timePattern = "[0-2][0-9]:[0-5][0-9]";
if (sTimeIn == null || sTimeOut == null || !sTimeIn.matches(timePattern) || !sTimeIn.matches(timePattern)) {
throw new IllegalArgumentException();
}
String[] timeIn = sTimeIn.split(":");
String[] timeOut = sTimeOut.split(":");
LocalTime localTimeIn = LocalTime.of(Integer.valueOf(timeIn[0]), Integer.valueOf(timeIn[1]));
LocalTime localTimeOut = LocalTime.of(Integer.valueOf(timeOut[0]), Integer.valueOf(timeOut[1]));
Duration duration;
if (localTimeOut.isAfter(localTimeIn)) {
duration = Duration.between(localTimeIn, localTimeOut);
} else {
Duration prevDay = Duration.ofHours(24).minusHours(localTimeIn.getHour()).minusMinutes(localTimeIn.getMinute());
Duration nextDay = Duration.between(LocalTime.MIDNIGHT, localTimeOut);
duration = prevDay.plus(nextDay);
}
System.out.printf("Time difference between %s and %s is %d hours and %d minutes\n", sTimeIn, sTimeOut,
duration.toHours(), duration.minusHours(duration.toHours()).toMinutes());
}
Можно использовать HTTP-модуль для получения сообщения об исключении, отслеживания стека и типа исключительной ситуации, который брошен методом веб-сервиса.
Сначала некоторый фон...
Если метод веб-сервиса выдает исключение, ответ HTTP имеет код состояния 500.
Если пользовательские ошибки будут от затем веб-сервиса, то возвратит сообщение об исключении и отслеживание стека клиенту как JSON. Например:{"Message":"Exception message","StackTrace":" at WebApplication.HelloService.HelloWorld() in C:\Projects\Stackoverflow Examples\WebApplication\WebApplication\HelloService.asmx.cs:line 22","ExceptionType":"System.ApplicationException"}
Когда пользовательские ошибки идут затем, веб-сервис возвращает сообщение по умолчанию клиенту и удаляет отслеживание стека и тип исключительной ситуации:{"Message":"There was an error processing the request.","StackTrace":"","ExceptionType":""}
Таким образом, то, что мы должны сделать, выделено пользовательские ошибки для веб-сервиса, и включите HTTP-модуль что:
Код ниже является примером HTTP-модуля, который делает это:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Web;
public class ErrorHandlerModule : IHttpModule {
public void Init(HttpApplication context) {
context.PostRequestHandlerExecute += OnPostRequestHandlerExecute;
context.EndRequest += OnEndRequest;
}
static void OnPostRequestHandlerExecute(object sender, EventArgs e) {
HttpApplication context = (HttpApplication) sender;
// TODO: Update with the correct check for your application
if (context.Request.Path.StartsWith("/HelloService.asmx")
&& context.Response.StatusCode == 500) {
context.Response.Filter =
new ErrorHandlerFilter(context.Response.Filter);
context.EndRequest += OnEndRequest;
}
}
static void OnEndRequest(object sender, EventArgs e) {
HttpApplication context = (HttpApplication) sender;
ErrorHandlerFilter errorHandlerFilter =
context.Response.Filter as ErrorHandlerFilter;
if (errorHandlerFilter == null) {
return;
}
string originalContent =
Encoding.UTF8.GetString(
errorHandlerFilter.OriginalBytesWritten.ToArray());
// If customErrors are Off then originalContent will contain JSON with
// the original exception message, stack trace and exception type.
// TODO: log the exception
}
public void Dispose() { }
}
Этот модуль использует следующий фильтр, чтобы переопределить содержание, отправленное клиенту и сохранить исходные байты (которые содержат сообщение об исключении, отслеживание стека и тип исключительной ситуации):
public class ErrorHandlerFilter : Stream {
private readonly Stream _responseFilter;
public List OriginalBytesWritten { get; private set; }
private const string Content =
"{\"Message\":\"There was an error processing the request.\"" +
",\"StackTrace\":\"\",\"ExceptionType\":\"\"}";
public ErrorHandlerFilter(Stream responseFilter) {
_responseFilter = responseFilter;
OriginalBytesWritten = new List();
}
public override void Flush() {
byte[] bytes = Encoding.UTF8.GetBytes(Content);
_responseFilter.Write(bytes, 0, bytes.Length);
_responseFilter.Flush();
}
public override long Seek(long offset, SeekOrigin origin) {
return _responseFilter.Seek(offset, origin);
}
public override void SetLength(long value) {
_responseFilter.SetLength(value);
}
public override int Read(byte[] buffer, int offset, int count) {
return _responseFilter.Read(buffer, offset, count);
}
public override void Write(byte[] buffer, int offset, int count) {
for (int i = offset; i < offset + count; i++) {
OriginalBytesWritten.Add(buffer[i]);
}
}
public override bool CanRead {
get { return _responseFilter.CanRead; }
}
public override bool CanSeek {
get { return _responseFilter.CanSeek; }
}
public override bool CanWrite {
get { return _responseFilter.CanWrite; }
}
public override long Length {
get { return _responseFilter.Length; }
}
public override long Position {
get { return _responseFilter.Position; }
set { _responseFilter.Position = value; }
}
}
Этот метод требует, чтобы пользовательские ошибки были выключены для веб-сервисов. Вы, вероятно, хотели бы сохранить пользовательские ошибки на для остальной части приложения, таким образом, веб-сервисы должны быть помещены в подкаталог. Пользовательские ошибки могут быть выключены в том каталоге только с помощью web.config, который переопределяет родительскую установку.
Я знаю, что это не отвечает на вопрос на - говорят, но я пошел на свои собственные поиски некоторое время назад для обнаружения этого и опустею врученный. Законченное обертывание каждого вызова веб-сервиса в попытке/выгоде и выгоды называет нашу программу регистрации ошибок. Сосет, но это работает.
В ASP.NET возможно поймать обработанные исключения всего выполнения с помощью глобального обработчика ошибок, хотя сообщение в блоге предполагает, что это не работало бы, но Вы могли экспериментировать с этим подходом, пытающимся повторно бросить ошибку в некотором роде?
Другая идея состояла бы в том, чтобы посмотреть на открытый исходный код elmah (Модули регистрации ошибок и Обработчики) для ASP.NET, который мог бы помочь, или у кого-то в том сообществе может быть идея.