Вычислите недостающие диапазоны даты и перекрывающиеся диапазоны даты между двумя датами

Вы можете использовать iText5 или iText7 для удаления потоков iref.

Блок iText5 ниже взят из http://forum.pdfsharp.net/viewtopic.php?f=2&t=693

static public PdfDocument Open(MemoryStream sourceStream)
  {
     PdfDocument outDoc = null;
     sourceStream.Position = 0;

     try
     {
        outDoc = PdfReader.Open(sourceStream, PdfDocumentOpenMode.Import);
     }
     catch (PdfSharp.Pdf.IO.PdfReaderException)
     {
        //workaround if pdfsharp doesn't support this pdf
        sourceStream.Position = 0;
        MemoryStream outputStream = new MemoryStream();
        iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(sourceStream);
        iTextSharp.text.pdf.PdfStamper pdfStamper = new iTextSharp.text.pdf.PdfStamper(reader, outputStream);
        pdfStamper.FormFlattening = true;
        pdfStamper.Writer.SetPdfVersion(iTextSharp.text.pdf.PdfWriter.PDF_VERSION_1_4);
        pdfStamper.Writer.CloseStream = false;
        pdfStamper.Close();

        outDoc = PdfReader.Open(outputStream, PdfDocumentOpenMode.Import);
     }

     return outDoc;
  }

У меня был переписать его для iText7 (все еще используя старый PDFSharp):

static PdfDocument CompatibleOpen(MemoryStream inputStream, PdfDocumentOpenMode openMode)
{
 PdfDocument pdfDocument = null;
 inputStream.Position = 0;

 try
 {
    pdfDocument = PdfReader.Open(inputStream, openMode);
 }
 catch (PdfSharp.Pdf.IO.PdfReaderException)
 {
    inputStream.Position = 0;
    MemoryStream outputStream = new MemoryStream();

    iText.Kernel.Pdf.WriterProperties writerProperties = new iText.Kernel.Pdf.WriterProperties();
    writerProperties.SetPdfVersion(iText.Kernel.Pdf.PdfVersion.PDF_1_4);

    iText.Kernel.Pdf.PdfReader pdfReader = new iText.Kernel.Pdf.PdfReader(inputStream);

    iText.Kernel.Pdf.PdfDocument pdfStamper = new iText.Kernel.Pdf.PdfDocument(pdfReader, new iText.Kernel.Pdf.PdfWriter(outputStream, writerProperties)); 

    iText.Forms.PdfAcroForm pdfForm = iText.Forms.PdfAcroForm.GetAcroForm(pdfStamper, true);
    if (!pdfForm.IsNull())
    {
       pdfForm.FlattenFields();
    }
    writerProperties.SetFullCompressionMode(false);

    pdfStamper.GetWriter().SetCloseStream(false);           
    pdfStamper.Close();

    pdfDocument = PdfReader.Open(outputStream, openMode);
 }
 return pdfDocument;
}

Я надеюсь, что это поможет кому-то пережить ту же боль, с которой я был, и сэкономит им несколько дней !!!

6
задан Quassnoi 22 June 2009 в 16:08
поделиться

3 ответа

Это небольшая вариация функции выравнивания пересекающихся интервалов времени в SQL Server :

Это один из редких случаев, когда курсор Подход на основе SQL Server быстрее, чем подход на основе набора:


CREATE FUNCTION mytable(@p_from DATETIME, @p_till DATETIME)
RETURNS @t TABLE
        (
        q_type VARCHAR(20) NOT NULL,
        q_start DATETIME NOT NULL,
        q_end DATETIME NOT NULL
        )
AS
BEGIN
        DECLARE @qs DATETIME
        DECLARE @qe DATETIME
        DECLARE @ms DATETIME
        DECLARE @me DATETIME
        DECLARE cr_span CURSOR FAST_FORWARD
        FOR
        SELECT  startDate, endDate
        FROM    mytable
        WHERE   startDate BETWEEN @p_from AND @p_till
        ORDER BY
                startDate 
        OPEN    cr_span
        FETCH   NEXT
        FROM    cr_span
        INTO    @qs, @qe
        SET @ms = @qs
        SET @me = @qe
        WHILE @@FETCH_STATUS = 0
        BEGIN
                FETCH   NEXT
                FROM    cr_span
                INTO    @qs, @qe
                IF @qs > @me
                BEGIN
                        INSERT
                        INTO    @t
                        VALUES ('overlap', @ms, @me)
                        INSERT
                        INTO    @t
                        VALUES ('gap', @me, @qs)
                        SET @ms = @qs
                END
                SET @me = CASE WHEN @qe > @me THEN @qe ELSE @me END
        END
        IF @ms IS NOT NULL
        BEGIN
                INSERT
                INTO    @t
                VALUES  (@ms, @me)
        END
        CLOSE   cr_span
        RETURN
END
GO

Эта функция сжимает каждый непрерывный набор пересекающихся диапазонов в один диапазон и возвращает диапазон и следующий за ним промежуток.

4
ответ дан 17 December 2019 в 04:51
поделиться

Не совсем понимая, какую проблему вы пытаетесь решить, вот мое решение некоторой проблемы, которое мне пришло в голову:

  1. Create table function (UDF) "все-даты", которые будут возвращать все даты в году.
  2. Преобразуйте ваши события в отдельные даты (одна строка события станет таким количеством строк, сколько дней в ней) путем внутреннего соединения событий со всеми датами , где дата находится между датами начала и окончания события ... Сохраните исходный идентификатор события.
  3. Выполните внешнее объединение дат-событий со всеми-датами (снова), чтобы найти пробелы или пропуски.
  4. Соедините даты событий сами с собой на , где даты такие же, но eventId не , чтобы найти совпадения.
1
ответ дан 17 December 2019 в 04:51
поделиться

бедняга, с postgresql вы можно сделать это просто:

(start1, end1) OVERLAPS (start2, end2) (start1, length1) OVERLAPS (start2, length2)

Это выражение возвращает истину, когда два периода времени (определяемые их конечными точками) перекрываются, и ложь, когда они не перекрываются. Конечные точки могут быть указаны как пары даты, времени или отметок времени; либо в виде даты, времени или отметки времени, за которой следует интервал.

SELECT (DATE '2001-02-16', DATE '2001-12-21') OVERLAPS (ДАТА '2001-10-30', ДАТА '2002-10-30'); Результат: правда ВЫБРАТЬ (ДАТА '2001-02-16', ИНТЕРВАЛ '100 дней') ПЕРЕПАД (ДАТА '2001-10-30', ДАТА '2002-10-30'); Результат: false

, но под sql server я не знаю ... извините

0
ответ дан 17 December 2019 в 04:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: